this is my program, its supposed to get an input from the user for the starting x value, stepping value, and an ending x value, the user also inputs the y function he likes, the graph is then supposed to graph it but i keep getting an error, any ideas?
clear all ; % clear memory
close all ; % close any open figures
drawnow ; % update screen now
clc ; % clear screen
display('** Welcome to Plotting Program **') ;
display(' ');
start=input('please enter starting x value:');
step=input('please enter ending x value:');
stop=input('please enter step value:');
y= double(input('please input your equation:'));
x=double(start:step:stop);
plot(x,y);
You can use str2func() to convert string input into a function handle:
y = input('Input only the RHS of your equation as a function of ''x'' and enclose in '': ')
y = str2func(['#(x)' y]);
plot(x,y(x))
Also note that double(start:step:stop) will not work, since you are converting chars to their ASCII mapping:
double('20')
ans =
50 48
Use instead str2double(input('...'))
Related
I have created this code to generate a 1 set of lottery numbers, but I am trying to make it so that the user can enter how many sets they want (input n), and it will print out as one long matrix of size nX6? I was messing around with a few options from online suggestions, but to no avail. I put the initial for i=1:1:n at the beginning, but I do not know how to store each run into a growing matrix. Right now it still generates just 1 set.
function lottery(n)
for i=1:1:n
xlow=1;
xhigh=69;
m=5;
i=1;
while (i<=m)
lottonum(i)=floor(xlow+rand*(xhigh-xlow+1));
flag=0;
for j=1:i-1
if (lottonum(i)==lottonum(j))
flag=1;
end
end
if flag==0
i=i+1;
end
end
ylow=1;
yhigh=26;
m=1;
lottonum1=floor(ylow+rand*(yhigh-ylow+1));
z = horzcat(lottonum, lottonum1);
end
disp('The lotto numbers picked are')
fprintf('%g ',z)
disp (' ')
The problem is that you are not storing or displaying the newly generated numbers, only the last set. To solve this, initialize z with NaNs or zeros, and later index z to store each set in a row of z, by using z(i,:) = lottonum.
However, you are using i as iterator in the while loop already, so you should use another variable, e.g. k.
You can also set z as an output of the function, so you can use this matrix in some other part of a program.
function z = lottery(n)
% init z
z = NaN(n,6);
for k = 1:n
xlow=1;
xhigh=69;
m=5;
i=1;
while (i<=m)
lottonum(i)=floor(xlow+rand*(xhigh-xlow+1));
flag=0;
for j=1:i-1
if (lottonum(i)==lottonum(j))
flag=1;
end
end
if flag==0
i=i+1;
end
end
ylow=1;
yhigh=26;
lottonum1 = floor(ylow+rand*(yhigh-ylow+1));
z(k,:) = horzcat(lottonum, lottonum1); % put the numbers in a row of z
end
disp('The lotto numbers picked are')
disp(z) % prettier display than fprintf in this case.
disp (' ')
end
The nice answer from rinkert corrected your basic mistakes (like trying to modify your loop iterator i from within the loop => does not work), and answered your question on how to store all your results.
This left you with a working code, however, I'd like to propose to you a different way to look at it.
The porposed architecture is to divide the tasks into separate functions:
One function draw_numbers which can draw N numbers randomly (and does only that)
One function draw_lottery which call the previous function as many times as it needs (your n), collect the results and display them.
draw_lottery
This architecture has the benefit to greatly simplify your main function. It can now be as simple as:
function Draws = draw_lottery(n)
% define your draw parameters
xmin = 1 ; % minimum number drawn
xmax = 69 ; % maximum number drawn
nballs = 5 ; % number of number to draw
% pre allocate results
Draws = zeros( n , nballs) ;
for iDraw=1:1:n
% draw "nballs" numbers
thisDraw = draw_numbers(xmin,xmax,nballs) ;
% add them to the result matrix
Draws(iDraw,:) = thisDraw ;
end
disp('The lotto numbers picked are:')
disp (Draws)
disp (' ')
end
draw_numbers
Instead of using a intricated set of if conditions and several iterators (i/m/k) to branch the program flow, I made the function recursive. It means the function may have to call itself a number of time until a condition is satisfied. In our case the condition is to have a set of nballs unique numbers.
The function:
(1) draws N integer numbers randomly, using randi.
(2) remove duplicate numbers (if any). Using unique.
(3) count how many unique numbers are left Nu
(4a) if Nu = N => exit function
(4b) if Nu < N => Call itself again, sending the existing Nu numbers and asking to draw an additional N-Nu numbers to add to the collection. Then back to step (2).
in code, it looks like that:
function draw = draw_numbers(xmin,xmax,nballs,drawn_set)
% check if we received a partial set
if nargin == 4
% if yes, adjust the number of balls to draw
n2draw = nballs - numel(drawn_set) ;
else
% if not, make a full draw
drawn_set = [] ;
n2draw = nballs ;
end
% draw "nballs" numbers between "xmin" and "xmax"
% and concatenate these new numbers with the partial set
d = [drawn_set , randi([xmin xmax],1,n2draw)] ;
% Remove duplicate
drawn_set = unique(d) ;
% check if we have some more balls to draw
if numel(drawn_set) < nballs
% draw some more balls
draw = draw_numbers(xmin,xmax,nballs,drawn_set) ;
else
% we're good to go, assign output and exit funtion
draw = drawn_set ;
end
end
You can have both functions into the same file if you want.
I encourage you to look at the documentation of a couple of Matlab built-in functions used:
randi
unique
I have this piece of code in Matlab which should take an Airfoil profile and increase the number of points so that when I plot the profile in another programme I will get a smoother curve.
clear
%reading an external data file
fid = fopen('NACA0015.txt');
a = fscanf(fid,'%g %g',[2 inf]); % It has two rows now.
a = a'; % matrix transpose
n = input('200') %e.g., n=35
for i=1:n
for j=1:2
fprintf('%12.7f',a(i,j)); %a(i,1) is first column, a(i,2) is 2nd col
end
fprintf('\n');
end
fclose(fid);
for i=1:n
x(i)=a(i,1); %x , y vectors
y(i)=a(i,2);
end
% use spline to create more points
xx=0:0.01:1 % e.g., step =0.01 (number of points = (1-0)/0.01=100)
yy = spline(x,y,xx); % xx and yy are new generated values of Naca0012
fprintf('\n print spline values \n');
plot(xx,yy,'ro')
hold on
plot(x,y,'*')
When I run this I get the error
Undefined function or variable 'x'.
Error in reading_external_data_and_spline (line 26)
yy = spline(x,y,xx); % xx and yy are new generated values of Naca0012
I am at a complete loss as to why this is not working when the x variable is clearly defined in the code, please could someone help me with this
It's how you're using input. The argument in input isn't the default value, it's the prompt text. If you type the command into the console and hit enter, you get this:
>> n = input('200')
200
n =
[]
>>
Input doesn't accept a default. If you really want to have an interactive prompt with a default answer, you want inputdlg:
answer = inputdlg('Enter a number of lines to parse', 'n', 1, '200');
n = str2double(answer);
note that inputdlg returns text always, so you need to convert to a number.
M = round(csvread('noob.csv'))
save projectDAT.dat M -ascii
load projectDAT.dat
mat = (projectDAT)
sum_of_rows(mat)
plotthegraph
This is my main script. I have a excel file, which opens up a 20 x 20 matrix in matlab. Now I have to call a function in this mainscript, which would find the sum of elements in a row for me and put them in a column vector. Here is my function:
function sumRow = sum_of_rows(mat)
[m n] = size(mat);
sumRow = zeros(m,1);
for i = 1:m;
for j = 1:n;
sumRow(i) = sumRow(i) + mat(i,j);
end
end
vec = sumRow;
end
I am required to plot a line graph using this column vector. I am supposed to call a function from the mainscript. The function should be able to take the input from this sum_of_rows function. I tried doing this:
function plotthegraph(~)
% Application for plotting the height of students
choice = menu('Choose the type of graph', 'Plot the data using a line plot', 'Plot the data using a bar plot');
if choice == 1
plot_line(sum_of_rows)
y = sum_of_rows
x = 1:length(y)
plot(x,y)
title('Bar graph')
xlabel('Number of characters')
ylabel('Number of grades')
elseif choice == 2
plot_bar(sum_of_columns)
end
Its not working out though. Can someone please help me out, I would really appreciate it. Thank you.
You could do the following to get rid of the sum_of_rows function:
sumRow = sum(mat,2);
The second argument tells the sum to add all the columns in the matrix rowwise, giving you the sum of each row in mat.
To plot this vector you need to pass it as input to your function. Also matlab takes care of the x values for you if you do not specify variable along, doing exactly what you did manually while defining x. Your function would look like this:
function plotthegraph(sum_of_rows)
% Application for plotting the height of students
prompt='Type 1 for line plot, 2 for bar';
choice=input(prompt)
if choice == 1
plot(sum_of_rows)
title('Line graph')
xlabel('Number of characters')
ylabel('Number of grades')
elseif choice == 2
bar(sum_of_rows)
end
end
So you'd have to call this function passing the sum of rows:
plotthegraph(sumRow)
I am using MATLAB version R2011a, a friend of mine is using R2014b which contains the function "Flip", which flips the order of elements, this function is vital to our program that compares Matrix'es.
My problem is R2011a does not have this function, it has fliplr,flipud and flipdim. I have tried using fliplr and then flipud to try and recreate the same function but eventually it doesn't work since i'm using the function corr which requires using that it's two arguments be the same dimensions.
I need advise on how to create the flip function that is available on R2014b.
The function that is problematic:
%This function gets the DNA signiture with the relative freq of each perm at
%the refernce text, the DNA signiture with the relative freq of each perm at
%the compare text, and the MaxPerm, and return the relative editor distance
%between the 2 texts.
function [distance]=EditorDistance2 (RefDNAWithFreq,CmpDNAWithFreq,MaxPerm)
if MaxPerm>2
MaxPerm=2;
end
str='Editor Distance compare begun';
disp(str);
distance=[];
for PermLength=1:MaxPerm
freq=sum(0:PermLength);
PermInitial=freq+1;
permEnd=freq+PermLength;
%create an ordered matrix of all the perms with length "PermLength"
%in the ref text
CurRefPerms=RefDNAWithFreq(:,freq:permEnd);
OrderedRefCurPerms=sortrows(CurRefPerms);
OrderedRefCurPerms=flip(OrderedRefCurPerms);
OrderedRefCurPerms(:,1)=[];
OrderedRefCurPerms=ZeroCutter(OrderedRefCurPerms);
%create an ordered matrix of all the perms with length "PermLength"
%in the cmp text
CurcmpPerms=CmpDNAWithFreq(:,freq:permEnd);
OrderedCmpCurPerms=sortrows(CurcmpPerms);
OrderedCmpCurPerms=flip(OrderedCmpCurPerms);
OrderedCmpCurPerms(:,1)=[];
OrderedCmpCurPerms=ZeroCutter(OrderedCmpCurPerms);
len1=size(OrderedRefCurPerms,1);
len2=size(OrderedCmpCurPerms,1);
edit=1;
matrix=zeros(len2,len1);
%initiate first row of the first stirng
for i=2:len1
matrix(1,i)=matrix(1,i-1)+1;
end
%initiate first column of the second stirng
for i=2:len2
matrix(i,1)=matrix(i-1,1)+1;
end
%start algoritem
for i=2:len2
for j=2:len1
if OrderedRefCurPerms(j-1,:)==OrderedCmpCurPerms(i-1,:)
edit=0;
end
if (i>2 & j>2 & OrderedRefCurPerms(j-1,:)==OrderedCmpCurPerms(i-2,:) & RefDNAWithFreq(j-2)==CmpDNAWithFreq(i-1) )
matrix(i,j)= min([matrix(i-1,j)+1,... deletion
matrix(i,j-1)+1,... insertion
matrix(i-2,j-2)+1,... substitution
matrix(i-1,j-1)+edit... transposition
]);
else
matrix(i,j) = min([matrix(i-1,j)+1,... deletion
matrix(i,j-1)+1,... insertion
matrix(i-1,j-1)+edit... substitution
]);
end
edit=1;
end
end
%The Distance is the last elment of the matrix.
if i~=1
tempdistance = matrix( floor( len2 / 3 ) , floor( len1 / 3 ) );
tempdistance=tempdistance/floor(len2/3);
else
tempdistance = matrix( len2,len1 );
tempdistance= tempdistance/len2;
end
tempdistance=1-tempdistance;
distance=[distance tempdistance];
end
end
I will further explain myself, the function which I am trying to use is A=flip(A)
The function that causes me problems is this one
%This function gets the DNA signiture with the relative freq of each perm at
%the refernce text, the DNA signiture with the relative freq of each perm at
%the compare text, and the MaxPerm, and return the corralation between the 2 texts.
function [Corvector]=CorrelationCompare(RefDNAWithFreq,CmpDNAWithFreq,MaxPerm)
str='corraltion compare begun';
disp(str);
%this vector will contain the corralation between the freqs of
%each perms vector(each length)
Corvector=[];
for PermLength=1:MaxPerm
freq=sum(0:PermLength);
PermInitial=freq+1;
permEnd=freq+PermLength;
%Cor is correlation between the 2 texts
refPerms=RefDNAWithFreq(:,freq);
cmpPerms=CmpDNAWithFreq(:,freq);
refPerms=ZeroCutter(refPerms);
cmpPerms=ZeroCutter(cmpPerms);
tempCor=corr(refPerms,cmpPerms);
Corvector =[Corvector tempCor];
% making a graph of the perms, and the relative freq of the texts.
x=ZeroCutter ( RefDNAWithFreq(:,PermInitial:permEnd) );
y1=refPerms;
y2=cmpPerms;
xchars=char(x);
Xcols=size(x,1);
o=ones(Xcols,1);
xco=mat2cell(xchars,o,PermLength);
xaxis=(1:Xcols);
figure
stem(xaxis,y1,'r');
hold
stem(xaxis,y2,'g');
set(gca,'XTick',xaxis)
set(gca,'XTickLabel',xco,'fontname','david');
xlabel('Perms');
ylabel('Perm frequency');
TitleOfGraph=sprintf('comapre between reference text to the compared, %d letters perm\n correlation=%f',PermLength,Corvector(PermLength));
legend('reference','compared');
title(TitleOfGraph);
end
end
The Error that I recieve when using a diffrent flip command is
??? Error using ==> corr at 102
X and Y must have the same number of rows.
Error in ==> CorrelationCompare at 27
tempCor=corr(refPerms,cmpPerms);
I apologize for the long codes but it's hard to explain it all since it's a big project and a lot of it was done by my partner
This should work for you -
function out = flip_hacked(A,dim)
%// Get an array of all possible dimensions
dims = 1:ndims(A);
%// Interchange first dimension and dim
dims(dim) = 1;
dims(1) = dim;
A1 = permute(A,[dims]);
%// Reshape A1 into a 2D matrix and then flip along the first dimension,
%// which would correspond to the flipping along dim and then interchange dim
%// and first dim again to keep the size of data same as input and elements
%// being flipped along dim for the desired output
A2 = reshape(A1,size(A1,1),[]);
out = permute(reshape(A2(end:-1:1,:),size(A1)),dims);
return;
It follows the same syntax as the official flip function that's stated in the official documentation as follows -
B = flip(A,dim) reverses the order of the elements in A along
dimension dim. For example, if A is a matrix, then flip(A,1) reverses
the elements in each column, and flip(A,2) reverses the elements in
each row.
In addition to the generic solution provided by Divakar you could simply use:
flip = #(A) A(end:-1:1, :);
A = flip(A);
To reverse the elements in each column of a matrix A. Even simpler:
A = A(end:-1:1, :);
Since it is not possible to have a script and a function definition in the same file , I thought to echo the function which I want to attach in the script such that I get a script with function code and then some usage with this function .
For example -
func1.m
function [result] = func1(x)
result=sqrt(x) ;
end
script1.m
echo(func1.m) ;
display(func1(9))
Desire output for script1.m
function [result] = func1(x)
result=sqrt(x) ;
end
display(func1(9))
3
Have you any idea for that ?
Since a convoluted solution was already proposed, why not stating the obvious?
Matlab has a built-in command that does exactly what you want. It is called type:
>> type('mean')
will give you this:
function y = mean(x,dim)
%MEAN Average or mean value.
% For vectors, MEAN(X) is the mean value of the elements in X. For
% matrices, MEAN(X) is a row vector containing the mean value of
% each column. For N-D arrays, MEAN(X) is the mean value of the
% elements along the first non-singleton dimension of X.
%
% MEAN(X,DIM) takes the mean along the dimension DIM of X.
%
% Example: If X = [0 1 2
% 3 4 5]
%
% then mean(X,1) is [1.5 2.5 3.5] and mean(X,2) is [1
% 4]
%
% Class support for input X:
% float: double, single
%
% See also MEDIAN, STD, MIN, MAX, VAR, COV, MODE.
% Copyright 1984-2005 The MathWorks, Inc.
% $Revision: 5.17.4.3 $ $Date: 2005/05/31 16:30:46 $
if nargin==1,
% Determine which dimension SUM will use
dim = min(find(size(x)~=1));
if isempty(dim), dim = 1; end
y = sum(x)/size(x,dim);
else
y = sum(x,dim)/size(x,dim);
end
You could use this:
function echo(mfile)
filename=which(mfile);
if isempty(filename)
fprintf('Invalid input - check you are inputting a string.');
return;
end
fid=fopen(filename,'r');
if (fid<0)
fprintf('Couldn''t open file.');
end
file=fread(fid,Inf);
fclose(fid);
fprintf('%s',file);
end
This will open a file, read it, and print it. Note that you need to provide the input as a string, i.e. with single quotes around it, and need to have '.m' at the end:
echo('fread.m')
Not
echo(fread.m) % This won't work
echo('fread') % This won't work
Just for completeness, there's also dbtype which prepends line numbers.