How to use multiple user inputs in a function in MATLAB? - matlab

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/

Related

How do I display full equations when calling for a function in Matlab?

I have a problem about displaying the output in the way I need it to, first let me show what I'm trying to do
The problem I'm trying to solve:
Write a function called printaltsum that takes an integer and prints the sum from 1 to the integer, where the addition and subtraction are alternated.
For example- printaltsum(4) MUST display exactly the following:
1=1
1+2=3
1+2-3=0
1+2-3+4=4
Please guide me in the right direction, I have been able to solve this problem to get final values, but I just can't get it to display the format it needs (all I get is the Right hand side of the equation and final value as answer).
When I call for my function it displays :
printaltsum(4)
1
3
0
4
ans =
4
as you can see I can't display the equations, but only the Right hand side of it and the final answer
Here is my code:
function sum = printaltsum(n)
sum=0;
for i=1:n;
if i==1
sum=1;
end
if rem(i,2)==0 && i ~=1
sum=sum+i;
end
if rem(i,2)==1 && i ~=1
sum=sum-i;
end
disp(sum)
end
end
you need to assembel the String to display yourselve, matlab wont do it.
So just add to every Operation the same in text.
first initialize an empty string:
str='';
When ever you do something to the sum, you do the same to the string in text, for example:
sum=1; % setting sum to 1
str='1'% the same in text
or for inside the loop:
sum=sum+i; % adding i to sum
str=[str '+' num2str(i)]% the same in text
at the end of the loop you can display the string:
disp(str)
Hope this helps

Using a variable in the 'to' of the 'for' loop in Matlab

The general syntax for a for loop in Matlab is :
for j = 1 to 5
%body
end
I want to have a variable whose value is calculated at run time depending on the user input to be used for controlling the number of times the for loop is to be run.
So I want to have:
m = input('Some Message');
n = ....% Some Calculations using user input 'm'
for j = 1 to n
%body
end
I tried this, but am getting an error -
Undefined function 'to' for input arguments of type 'char'.
Matlab is considering the variable n as a character instead of a variable.
P.S: I am new to Matlab, I searched a lot online, but couldn't get a solution for this. Please help.
The error message seems quite readable. This it not valid Matlab syntax. You would write a for loop of n repititons like this
m = input('Some Message: ');
if strcmp(m, 'foo')
n = 7;
else
n = 5;
end
for j = 1:n
fprintf('%d\n', j);
end
Actually, have you tried this syntax:
for j=1:n
%body
end
I don't see the word "to" in the docs. So the for loop syntax you have above would not be valid Matlab syntax. The other thing to consider is that n is being interpreted as a character and not a number.

How to manipulate and assign parts of a MATLAB field - Comma-separated list assignment

Consider the following MATLAB struct:
a(1).num=1; a(2).num=2; a(3).num=3;
The thing I want to do is to replace some of the elements of num with the old value minus a (scalar) number. For example, I would like to subtract 1 from a(2).num and a(3).num.
I already tried different ways:
a(2:3).num=a(2:3).num-1;
??? Error using ==> minus Too many input arguments.
Next try:
>>a(2:3).num=[a(2:3).num]-1;
??? Insufficient outputs from right hand side to satisfy comma separated list
expansion on left hand side. Missing [] are the most likely cause.
And last:
>> [a(2:3).num]=[a(2:3).num]-1;
??? Error using ==> minus
Too many output arguments.
arrayfun couldn´t help either.
Probably there is a quite easy answer to this question, but I couldn´t find any.
Easiest is a two-line solution:
C = num2cell([a(2:3).num]-1);
[a(2:3).num] = C{:}
Nicest is to have a function like deal, but with a function applied to each argument:
function varargout = fcnDeal(varargin)
%// (Copied from MATLAB's deal()
if nargin==1,
varargout = varargin(ones(1,nargout));
else
if nargout ~= nargin-1
error('fcnDeal:narginNargoutMismatch',...
'The number of outputs should match the number of inputs.')
end
%//...Except this part
varargout = cellfun(varargin{1}, varargin(2:end), 'UniformOutput', false);
end
end
Then what you want to do is just a matter of
[a(2:3).num] = fcnDeal(#(x)x-1, a(2:3).num)
You can manipulate them in the loop
index = [1,2]
for i = index
a(i).num = a(i).num - 1;
end

Matlab: how to implement a dynamic vector

I am refering to an example like this
I have a function to analize the elements of a vector, 'input'. If these elements have a special property I store their values in a vector, 'output'.
The problem is that at the begging I don´t know the number of elements it will need to store in 'output'so I don´t know its size.
I have a loop, inside I go around the vector, 'input' through an index. When I consider special some element of this vector capture the values of 'input' and It be stored in a vector 'ouput' through a sentence like this:
For i=1:N %Where N denotes the number of elements of 'input'
...
output(j) = input(i);
...
end
The problem is that I get an Error if I don´t previously "declare" 'output'. I don´t like to "declare" 'output' before reach the loop as output = input, because it store values from input in which I am not interested and I should think some way to remove all values I stored it that don´t are relevant to me.
Does anyone illuminate me about this issue?
Thank you.
How complicated is the logic in the for loop?
If it's simple, something like this would work:
output = input ( logic==true )
Alternatively, if the logic is complicated and you're dealing with big vectors, I would preallocate a vector that stores whether to save an element or not. Here is some example code:
N = length(input); %Where N denotes the number of elements of 'input'
saveInput = zeros(1,N); % create a vector of 0s
for i=1:N
...
if (input meets criteria)
saveInput(i) = 1;
end
end
output = input( saveInput==1 ); %only save elements worth saving
The trivial solution is:
% if input(i) meets your conditions
output = [output; input(i)]
Though I don't know if this has good performance or not
If N is not too big so that it would cause you memory problems, you can pre-assign output to a vector of the same size as input, and remove all useless elements at the end of the loop.
output = NaN(N,1);
for i=1:N
...
output(i) = input(i);
...
end
output(isnan(output)) = [];
There are two alternatives
If output would be too big if it was assigned the size of N, or if you didn't know the upper limit of the size of output, you can do the following
lengthOutput = 100;
output = NaN(lengthOutput,1);
counter = 1;
for i=1:N
...
output(counter) = input(i);
counter = counter + 1;
if counter > lengthOutput
%# append output if necessary by doubling its size
output = [output;NaN(lengthOutput,1)];
lengthOutput = length(output);
end
end
%# remove unused entries
output(counter:end) = [];
Finally, if N is small, it is perfectly fine to call
output = [];
for i=1:N
...
output = [output;input(i)];
...
end
Note that performance degrades dramatically if N becomes large (say >1000).

MATLAB setting matrix values in an array

I'm trying to write some code to calculate a cumulative distribution function in matlab. When I try to actually put my results into an array it yells at me.
tempnum = ordered1(1);
k=2;
while(k<538)
count = 1;
while(ordered1(k)==tempnum)
count = count + 1;
k = k + 1;
end
if(ordered1(k)~=tempnum)
output = [output;[(count/537),tempnum]];
k = k + 1;
tempnum = ordered1(k);
end
end
The errors I'm getting look like this
??? Error using ==> vertcat
CAT arguments dimensions are not consistent.
Error in ==> lab8 at 1164
output = [output;[(count/537),tempnum]];
The line to add to the output matrice was given to me by my TA. He didn't teach us much syntax throughout the year so I'm not really sure what I'm doing wrong. Any help is greatly appreciated.
If you're building the matrix output from scratch, you should make sure it hasn't already been initialized to anything. To do this, you can set it to the empty matrix at the beginning of your code:
output = [];
Also, if you know how large output is going to be, your code will run more efficiently if you preallocate the array output and index into the array to assign values instead of appending values to it. In your case, output should have the same number of rows as there are unique values in the array ordered1, so you could use the function UNIQUE to preallocate output:
nRows = numel(unique(ordered1)); %# Get the number of unique values
output = zeros(nRows,2); %# Initialize output
You would then have to keep a separate counter (say r) to track which index into output you will be adding to next:
...
output(r,:) = [count/537 tempnum]; %# Overwrite a row in output
r = r+1; %# Increment the row index
...
Some additional advice...
Even if you solve the error you are getting, you're going to run into more with the code you have above:
I believe you are actually computing a probability density function (or PDF) with your code. In order to get the cumulative distribution function (or CDF), you have to perform a cumulative sum over the final values in the first column of output. You can do this with the function CUMSUM:
output(:,1) = cumsum(output(:,1));
Your loop will throw an error when it reaches the last element of ordered1. The value of k can become 538 in your inner while loop, which will then cause an error to be thrown when you try to access ordered1(k) anywhere. To get around this, you will have to add checks to the value of k at a number of points in your code. One such point is your inner while loop, which can be rewritten as:
while (k <= 537) && (ordered1(k) == tempnum)
count = count + 1;
k = k + 1;
end
This solution uses the short-circuit AND operator &&, which will first check if (k <= 537) is true or false. If it is false (i.e. k > 537), the second logical check is skipped since its result doesn't matter, and you avoid the error that would result from evaluating ordered1(k).
Bonus MATLAB coolness...
MATLAB has a lot of cool functions that can do a lot of the work for you. One such function is ACCUMARRAY. Your TA may want you to do things using loops like you have above, but you can actually reduce your whole code to just a few lines like so:
nValues = numel(ordered1); %# Get the number of values
p = accumarray(ordered1,ones(size(ordered1)))./nValues; %# Create a PDF
output = [cumsum(p) unique(ordered1)]; %# Create the CDF output