How to recall the answer of an if statement in matlab? - matlab

I am writing a function, which is suppose to give the result of the following if statement:
s=some scalar
i=some scalar ;
if y(s,i)==L
U(1,i)==0
else disp('Never binding') ;
end
How can I store the "answer" so that the name given to the answer is the output of the function?
for example: ans=R and function R=myfunction(i,s)
Is this possible?
for example if i run my code:
if y(8,1)==L
U(1,1)==0
else disp('Never binding')
end
ans =
X1_2*a - P1_2*X1_2 - X1_2^2*b + X1_2*(LL*(g1_2 + g2_1) + LL*(g1_3 + g3_1)) == 0
or another case:
if y(1,1)==L
U(1,1)==0
else disp('Never binding')
end
Never binding
Here is the code for the complete function:
function R=myIR1(s, n , agent)
x = 'HL'; %// Set of possible types
K = n; %// Length of each permutation
%// Create all possible permutations (with repetition) of letters stored in x
C = cell(K, 1); %// Preallocate a cell array
[C{:}] = ndgrid(x); %// Create K grids of values
y = cellfun(#(x){x(:)}, C); %// Convert grids to column vectors
y = [y{:}];
e=size(y,1);
X = sym('X',[n e], 'positive' );
P = sym('P',[n e], 'positive' );
G=sym('g' , [n,n]) ;
syms c a b ;
s=s;
A = char( zeros(n,2*n) ) ;
for col=1:n
Acol = [col col+1] + (col-1) ;
A(:,Acol) = [ y(s,col)*ones(n,1) y(s,:).' ] ;
end
A1 = reshape( cellstr( reshape(A.',2,[]).' ) , n , n ).' ;
B=A1.*(G+G') ;
B(logical(eye(size(B)))) = 0 ;
for i=1:n
U(i)=[a*X(i,s) - b*(X(i,s))^2 + X(i,s)*(sum(B(:,i).*X(:,s))) - X(i,s)*P(i,s)];
end
agent=agent ;
syms H L ;
i=agent ;
if y(s,i)==L
U(1,i)==0
else disp('Never binding') ;
end
IR is not assigned to anything, I want to assign it to the answer of the if statement..
Thank you

Yes, just assign R to be whatever you want inside the function body. When the function terminates, whatever R was assigned to is the final output that gets sent back to the user.
For example:
function R = myfunction(i,s)
...
...
...
R = ... ;%// Assign the value of R you want here
...
...
end
Then in the MATLAB Command Prompt, you would do:
R = myfunction(i,s);
When calling this function, R will contain whatever you assigned it to be in the function itself. However, you need to make sure that R gets assigned to something before the function terminates. If you don't, then MATLAB will give you an error telling you that you forgot to assign R something as it's expected to be the output.
Given your code, it looks like the main assignment that you want to store is done in the if statement at the end of your code. You're actually not storing that assignment to a variable. In particular:
if y(s,i)==L
U(1,i)==0
else disp('Never binding') ;
end
If you don't assign a variable to something, it automatically gets stored in a variable called ans, which is what you're echoing to the command prompt as you're not placing a semi-colon in front of the U(1,i) == 0 statement. I believe you want to take this output and assign it to R as R is the final output variable you want, so just do this. Note that your output variable is called IR and not R so make sure you change the output variable to R in the function:
if y(s,i)==L
R = U(1,i) == 0;
else disp('Never binding') ;
end
Place a semi-colon at the end of the statement so it doesn't unnecessarily echo the output to the screen.

Related

Brace indexing is not supported for variables of this type

When I run the code below I got this error Brace indexing is not supported for variables of this type.
function [R, Q] = rq_givens(A)
Q = { eye(size(A,2)) };
R = { A };
I =eye(size(A,1));
Qs={ };
k=1;
for i=1:size(A,2)
for j= size(A,1):-1:i+1
y= -A(j,i);
x= A(i,i);
alpha = atan(y/x);
c = cos(alpha);
s= sin(alpha);
temp = I;
temp(i,i)=c;
temp(i,j)=-s;
temp(j,i)=s;
temp(j,j)=c;
A = temp * A;
Qs{k} = temp;
k=k+1;
end
end
Q=I;
for i=k-1:-1:1
Q = Q*Qs{i};
end
Q= Q';
R= A;
end
It's an assignment that I am doing so all I can do is to change the function above,
The code to call the function is below and must stay the same.
A = randn(6,4);
[R,Q] = rq_givens(A)
for i = 1:length(R)
disp("Q orthonormal?")
Q{i}*Q{i}'
Q{i}'*Q{i}
disp("R upper triangular?")
R{i}
end
R{end}*Q{end} - A % Equal ?
Data types of R, Q are changed to numeric type from cell type inside function call.
At the second line, R is cell array, but the last line of function "rq_given" changes the type of R to numeric matrix.
Thus, R{i} is invalid. Similar issue can be seen with Q also.

Fibonacci function not accepting 0 and not displaying the last term only

I wrote a function that displays the Fibonacci sequence up to the nth term. The code runs fine, but I want to make two changes and am not sure how to do so.
Here is my code:
function [ F ] = get_fib( k )
F(1) = 1;
F(2) = 1;
i = 3;
while k >= i;
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
end
The first problem is that the code does not accept 0 as an input. I tried changing the function to:
function [ F ] = get_fib( k )
F(0) = 0;
F(1) = 1;
F(2) = 1;
i = 3;
while k >= i;
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
end
But the following error appears:
Attempted to access F(0); index must be a positive integer or logical.
Error in get_fib (line 2)
F(0) = 0;
I would also like the code to display the last term in the sequence, rather than the entire sequence.
I changed the function to:
function [ F ] = get_fib( k );
F(1) = 1;
F(2) = 1;
i = 3;
while k >= i;
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
term = F(k)
end
but the sequence it still being assigned to ans.
How can I make my function accept 0 as an argument and only display the last term of the sequence?
First let's get your function to output just the last item in the sequence. You're setting term like this:
term = F(k);
Which is good (notice I added the ; at the end, though). But the return value from your function is F. You need to change it to term.
function [ term ] = get_fib( k )
%// ^^^^- change this ^-- semicolon not necessary here
Now, to handle an input of 0, you can add a special check for zero:
function [ term ] = get_fib( k )
if k == 0
term = [];
return;
end
while k >= i
%// ^-- semicolon not needed here, either
<the rest of your code>
The semicolons after the function header and the while statement don't hurt anything, they just represent empty statements. But they might be misleading, so it's best to remove them.
The semicolon after the assignment to term prevents the ans = ... line from printing out to the console.
To address your first problem, F(0) is not a valid call. This is because MATLAB indexing starts from 1. In other words, the first element of a matrix is index 1. There is no 0th index of a matrix in MATLAB. See here for why MATLAB indexing starts from 1. What I would recommend to address this is to shift your output array by one index.
Thus, your code for the function should be:
function [ F ] = get_fib( k )
k = k + 1
F(1) = 0; % 0th Fibonacci term
F(2) = 1; % 1st Fibonacci term
F(3) = 1; % 2nd Fibonacci term
i = 4;
while k >= i
F(i) = F(i-1) + F(i-2);
i = i + 1;
end
term = F(k)
end
To address your second problem, it would depend on what you want. Do you (1) want the last term in the sequence to be returned when you call term = get_fib(k)or (2) want the last term of the sequence to be displayed and the entire sequence to be returned?
To achieve (1), fix the top line of your code to function term = F(k). To achieve (2), call the function with F = get_fib(some_number), as #rayryeng stated.
Since others already pointed out how to fix your code, I'd like to show you one approach to calculate the nth Fibonacci number without relying on the F(n-1) and F(n-2) terms calculation.
It involves the golden ratio, and you can read more about its relationship to the Fibonacci sequence here.
function [ F ] = get_fib( n )
% Changed your input variable from k to n (standard notation)
Phi = (1+sqrt(5))/2; % Golden ratio value
F = round((Phi^n - ((-1)^n)/(Phi^n))/sqrt(5)); %nth fibonacci number
end
Since you are only interested in the last value of the sequence, it could speed up the calculation for large values of n.
Note i have rounded the output (F) to avoid floating point arithmetic errors.

Stopping the output of a for cycle in matlab

I'm facing an issue with this simple Fibonacci number generator program:
function f = fibonr(n)
f(1) = 1;
f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
end
If I want to display only the n-th number of the sequence, what adjustments should I make?
function f = fibonr(n)
f = zeros(n,1); %//initialise the output array
f(1,1) = 1;
f(2,1) = 1;
for ii = 3:n
f(ii,1) = f(ii-1,1) + f(ii-2,1);
end
%//create a string with text and variables
str = sprintf('The %d th number in the Fibonacci sequence is %d',n,f(ii,1));
disp(str) %//display your output.
end
first up: don't use i as a variable. Secondly, I switched to using column vectors, since MATLAB processes them faster, as well as I initialised the array, which is way faster (hence the shiny orange wiggles below your f(i)= line).
Call your function:
output = fibonr(10);
The 10 th number in the Fibonacci sequence is 55
If you use e.g. n=20 and still want the 10th argument just call output(10)
if you want the specified output right away you can use nargin. This code will give you all of the sequence if you call fibonr(n), or you can specify a vector to get the fibonacy numbers at said positions. If you are interested in both, your specified output and all the numbers, you can call the function with:
[output, fibnumbers] = fibonr(n,v);
function [output,f] = fibonr(n,v)
f(1) = 1;
f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
if nargin() > 1
output = f(v);
else
output = f;
end

In matlab how to use if loop having condition (a is a scalar number and is equal to any element in a vector v of n length)

I have a function replace_me which is defined like as: function w = replace_me(v,a,b,c). The first input argument v is a vector, while a, b, and c are all scalars. The function replaces every element of v that is equal to a with b and c. For example, the command
x = replace_me([1 2 3],2,4,5); returns x as [1 4 5 3].
The code that I have created is
function w = replace_me(v,a,b,c)
[row,column]=size(v);
new_col=column+1;
w=(row:new_col);
for n=(1:column)
if a==v(n)
v(n)=b;
o=n;
d=n-1;
u=n+1;
for z=1:d
w(z)=v(z);
end
for z=u:column
w(z+1)=v(z);
end
w(o)=b;
w(o+1)=c;
end
end
end
It works perfectly fine for x = replace_me([1 2 3],2,4,5); I get required output but when I try x = replace_me([1 2 3], 4, 4, 5) my function fails.
To resolve this problem I want to use an if else statements having conditions that if a is equal to any element of vector v we would follow the above equation else it returns back the vector.
I tried to use this as if condition but it didn't worked
if v(1:column)==a
Any ideas
I'm not entirely sure if I understand what you are trying to achieve, but form what I understand you're looking for something like this:
function [v] = replace_me(v,a,b,c)
v = reshape(v,numel(v),1); % Ensure that v is always a column vector
tol = 0.001;
aPos = find( abs(v-a) < tol ); % Used tol to avoid numerical issues as mentioned by excaza
for i=numel(aPos):-1:1 % Loop backwards since the indices change when inserting elements
index = aPos(i);
v = [v(1:index-1); b; c; v(index+1:end)];
end
end
function w = move_me(v,a)
if nargin == 2
w=v(v~=a);
w(end+1:end+(length(v)-length(w)))=a;
elseif isscalar(v)
w=v;
else
w=v(v~=0);
w(end+1)=0;
end
end

change the variables of a function with two outputs in a loop in matlab

I have a function which gives me two outputs, i need to use it in a for loop to create different variables, and i want to use them later in next loops. so i need to change their name during the for loop when they are created.
something like this:
for l=1:L
[A(l),B(l)] = function(l);
end
how can i do this so i could have A1,A2,... or B1,B2,....
thanks
If you do not wish to use cell arrays you can use structure with dynamic field names:
for l = 1:L
afn = sprintf('A%d', l ); % field name for first output
bfn = sprintf('B%d', l ); % field name for second output
[s.(afn) a.(bfn)] = func( l );
end
fieldnames( s ); % see all created variable names
Here is an example that you can modify to your needs.
function main // because we need to call `func`
L = 5; // max num of iterations
for l = 1:L
// replace `func` with the name of your function
eval(['[A' num2str(l) ', B' num2str(l) '] = func(' num2str(l) ')'])
end
end
// your function goes here
function [s, c] = func(x)
s = x*x;
c = s*x;
end