Good day all, I'm currently writing a user function to collect user input for calculations. One of the variables (T) will be entered as an array of values, and I'm having trouble rejecting this input if ANY value of the array is negative. I was thinking of using an ifelse construct nested in the while loop. I want the function to loop until
proper inputs are made. Code is pasted below, any help would be greatly appreciated.
function [V,T,A] = input
%This fn collects user input for time, velocity and angle of departure
V = input('Enter the inital velocity in m/s: \n ');
T = input ('Enter the time in seconds: \n ');
A = input ('Enter the angle of departure in radians: \n ');
while ~any(T) || A < 0 %We will reject negative angle values and negative time values.
fprintf('Error! Time and Angle values must be positive! Try Again.\n\n')
T = input ('Enter the time in seconds: \n ');
A = input ('Enter the angle of departure in radians: \n ');
end
end
Related
The code so far:
function [fr]=frictionFactorFn(rho,mu,e,D,L,Q,f0,tol,imax)
format long
CS=(pi*D^(2))/4;%Cross sectional area of pipe
v=Q/CS;%velocity
Re=(rho*v*L)/mu;
iter=1;i=1;fr(1)=f0;
while 1
fr(i+1)=(-1.74*log((1.254/(Re*sqrt(fr(i))))+((e/D)/3.708)))^-2;%substitution for root finding
iter=iter+1;
if abs(fr(i+1)-fr(i))<tol || iter>=imax
break;
end
i=i+1;
end
fprintf('\n The Reynolds number is %f\n',Re);
plot(0:iter-1,fr);
xlabel('Number of iteration'),ylabel('friction factor');
end
It gave me the right converged value of f=0.005408015, but I would like to plot the iteration
Possibly by storing the values of f upon each iteration in an array. In this example the array is called Store_f and is plotted after the while-loop is completed. The variable Index below is used to indicate which cell of array Store_f the value should be saved to.
function [f_vals] = frictionfactorfn()
Index = 1;
while (Condition)
%Calculation code%
Store_f(Index) = f;
Index = Index + 1;
end
disp(num2str(f))
plot(Store_f,'Marker','.');
xlabel('Iteration'); ylabel('Value');
end
I have difficulty in writing an algortihm that takes three numbers as input from the user and calculates the maximum of them. I'm trying to do these by using function, however, I get an error message: "Undefined function 'calc' for input arguments of type 'char'.
Error in Untitled (line 2) calc(numbers); "
Here's my code: (I'm new at coding so there may be other types of errors:))
numbers= input('Enter three numbers to find out maximum of them:','s');
calc(numbers);
maxi
function [ maxi ] = calc( numbers(1),numbers(2),numbers(3) )
%UNTÄ°TLED2 Summary of this function goes here
% Detailed explanation goes here
maxi= numbers(1);
if numbers(2)>maxi
maxi= numbers(2)
end
if numbers(3)>maxi
maxi= numbers(3)
end
end
As you say that "I'm new at coding", I thought I'd describe a couple of different approaches for this.
Reading the input
You could do as H.Ghassami suggests and read the input one by one.
This is probably the better option as there is some fault handling
built into it. The user can only enter one input at a time and there
is check that the inputs is evaluable (a number or a variable from
the current workspace). The rutin could get a little bit more general by adding a variable for the number of inputs to get.
numberOfInputs = 3;
number = zeros(1, numberOfInputs);
for idx = 1:numberOfInputs
% Get the number of inputs declared in numberOfInputs
number(idx) = input( sprintf('Enter number %d: ', idx));
end
You could also let the user enter all the numbers at once by, as the example in your question, add a 2nd argument 's' to input. The input is now treated as a string. The user has to separate the input numbers in some way, preferable with a whitespace. You then have to convert to string to a number vector.
numberOfInputs = 3;
number = input( sprintf('Enter %d numbers separated by whitespaces\n', numberOfInputs), 's');
number = str2num(number); % Convert to number array
You should probably do some check on the number array to see that it is valid (numbers of the correct amount)
Getting the max
Matlab has an buildin function for this. So you could just write
maxNumber= max(number);
or if you, perhaps for the exercise, would like to use an if structure you could make it more general with a for loop
maxNumber = number(1);
for idx = 2:numberOfInputs
if maxNumber < number(idx)
maxNumber = number(idx);
end
end
-
The entire solution could be encapsulated in a function
function maxNumber = getMaxInput(numberOfInputs)
Your first mistake is input . It just get just one string from user, but you need three numbers.
Second one is the next line in your script. When you calculate the numbers, you should send output to a variable. Also you should change the calc parameters.
Put this code in your script instead of your code :
number1= input('Enter number1:');
number2= input('Enter number2:');
number3= input('Enter number3:');
maxi=calc(number1,number2,number3)
%---------------------------------------------------
function [ maxi ] = calc( numbers1,numbers2,numbers3 )
%UNTÄ°TLED2 Summary of this function goes here
% Detailed explanation goes here
maxi= numbers1;
if numbers2>maxi
maxi= numbers2;
end
if numbers3>maxi
maxi= numbers3;
end
end
refrence to read for you: http://matlabgeeks.com/tips-tutorials/getting-user-input/
I have a two-track model implemented in simulink. To control the velocity I use a PID-controller, so that the the output of the velocity looks like this:
now I want to implement a MATLAB function or simulink block that tracks the time when the velocity reaches a steady-state-behaviour and puts it into some kind of storage. I tried to implement something like this via the following MATLAB function with MATLAB-function-block:
function y = fcn(t,v,dv,tv)
%#codegen
if (v==tv+0.01) & (dv<0)
y=t
end
t is the clock-signal, v the velocity, dv the first derivation of the velocity and tv is the targetvelocity. The problem about this function is that there "y is not defined on some execution paths". do you have any ideas how to make this work?
I solved the problem without a MATLAB function using the simulink blocks data store memory and its read & write blocks. The signal that is coming in from bottom right side is the momentary velocity. The if statement is
(u1 >= 22.2) & (u1<=22.3) & (u2<0)
Since simulink is using time steps and the momentary velocity will never be exactly 22.2, you can not use u1==22.2
In SimuLink add a second output and a fifth input to your function. Then use that new output as a feedback to the function.
function [y, output] = fcn(t,v,dv,tv,input)
y = 0;
output = input;
if (v == tv + 0.01) && (dv < 0)
y = t;
if (input == -1)
output = t;
end
end
Attach the output to an IC block where you set the input initial value to -1 or whatever value you want to use. Then attach the IC block to the input of the function. output will be feedback constantly through the function. Once it's set it will reatin it's value forever.
function y = fcn(t,v,dv,tv)
%#codegen
y = zeros(length(t),1); % Initialise the array
for ii = 1:length(t)
if (v==tv+0.01) & (dv<0)
y(ii)=t;
else
y(ii)=0;
end
end
y(y==0)=[];
end
Two changes: added a semicolon after y=t to force it to not print it every time it is set. Second, your question, else y=[];, which means that y will be an empty matrix if you do not adhere to your if statement.
It now stores a 0 each time you do not adhere to the if statement. The line y(y==0)=[]; deletes all zeros, comment this line if you want your y to be the same length as the input variables.
function y = fcn(t,v,dv,tv)
%#codegen
y = zeros(length(t),1); % Initialise the array
ii=1;
while exist(t)
if (v==tv+0.01) & (dv<0)
y(ii)=t;
else
y(ii)=0;
end
ii = ii+1;
end
y(y==0)=[];
end
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, :);
Hi I am writing a program in which the user inputs dimensions for a matrix, recieves a random matrix with the specified dimesions, and through use of a for loop is returned the maximum values of each row and column.
Here is the code I have for the function I used to find the max of each row
function outmax = mymaxq (q)
outmax = q (1);
for i = 2:length (q)
if q(i) > outmax
outmax = q(i);
end
end
end
The code for the function to find the max of each column:
function outmax2 = mymaxcol(z)
outmax2 = z(1);
for i = 2: length (y)
if z(i) > outmax2
outmax2 = z(i);
end
end
end
The code for the overall script:
rows = input('Enter the number of rows: ');
columns = input ('Enter the number of columns: ');
mat = round(rand(rows , columns)*(30-1)+1)
[r,c] =size (mat);
for x = 1:r
q = mat(x,:);
outmax = mymaxq(q);
fprintf ('The max of row %d is %d.\n',x,outmax)
end
for y = 1:c
z = mat(:,y);
outmax2 = mymaxcol(z);
fprintf ('The max of column %d is %d.\n',y,outmax2)
end
However the column function is not working properly. My guess is because the length of the column vector is 1. What do I do to make it so the function works properly. Suggestions for using things other than length?
Why not just use max(mat,[],1) (gives maximum of each column) and max(mat,[],2) (gives maximum of each row)?
In any case, in the third line of your second function, y should be z. Or better, use only the first function. The second does exactly the same thing.