In Matlab I keep getting undefined variable or function error despite clearly defining the variable - matlab

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.

Related

plotting a graph by calling a function

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)

Flip order of elements function in MATLAB R2011a

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, :);

matlab - is there a function which echo text of file ?

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.

program isnt working because of an error in y

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('...'))

Matlab fminsearch get's stuck in first iteration

I'm doing an optimization on a simulated robot's walk with the fminsearch method. What I did is create a function (the objective function) that writes to a text file the walking parameters (the input of fminsearch), opens the simulator (in webots) which writes the result of the walk in a text file and closes itself and then the objective returns the value in that text file. To sum up- the objective function get's a 8x12 matrix of leg position's and returns a scalar which indicates how good the walk is.
This works and the position values really change each iteration and the objective value improved indeed.
But here is the problem- I want to follow the function's value in each iteration (preferably by plot) and when I do that I get only the function's value at the first iteration and I can't understand why.
Here's the code:
options= optimset( 'PlotFcns', #optimplotfval);
[position,fval] = fminsearch(#callWebots,pos_start,options);
I tried displaying the results too and the same problem occurred (it displayed only the first iteration):
options= optimset(options, 'Display', 'iter-detailed');
I even tried to write an output function which will plot the fval and occurred with the same problem.
I would be grateful if you have any ideas why this can be...
Thank you in advanced
Here's the objective function:
function [objFun]=callWebots(pos)
%Open Motion File
filePath= fullfile('C:\Users\student\Documents\Webots\worlds', 'motion_trot_opt.motion');
data=convertToData(pos,filePath);
fout=fopen(filePath,'w');
%Write Motion File
for row=1:size(data,1)
for col=1:size(data,2)
if(col>1)
fprintf(fout, ',');
end
fprintf(fout, '%s', data{row,col});
end
fprintf(fout,'\n');
end
fclose(fout);
system('C:\Users\student\Documents\Webots\worlds\robot_full_withGPSLighter.wbt');
% Get result and return to main function
resfilePath= fullfile('C:\Users\student\Documents\Webots\worlds', 'result.txt');
fres=fopen(resfilePath);
result = textscan(fres, '%f');
fclose(fres);
objFun=cell2mat(result);
And the call for the objective function:
function [position,fval]=optCall()
%Read Initial Motion File Into CELL
filePath= fullfile('C:\Users\student\Documents\Webots\worlds', 'motion_trot_opt.motion');
fin=fopen(filePath);
ii = 1;
while 1
tline = fgetl(fin);
if (tline == -1)
break;
end
SplitedRow(ii,:) = regexp(tline, ',', 'split');
ii = ii+1;
end
fclose(fin);
%Convert from double to Data
[n,m] = size(SplitedRow);
pos_start = cellfun(#str2double,SplitedRow(2:end,3:end));
options= optimset( 'PlotFcns', #optimplotfval);
options= optimset(options, 'Display', 'iter-detailed');
[position,fval] = fminsearch(#callWebots,pos_start,options);