Extracting values from a function - matlab

I have a loop within a function that spits out values similar to:
E = 3,2,1,-1,-2
for
i = 1,2,3,4,5
I'm trying to extract the position where E becomes negative and then identify the step before it.
My attempt was something like
finalPos = find(i(E<0));
Firstly, it just doesn't seem right (my matlab syntax knowledge is poor as)
but secondly even if it did work it would tell me all positions where E is less than 0, where I only want to know the position before where E is no longer positive. i.e. E = 1, i = 3
Any help would be greatly appreciated!

Check the below:
E = [3,2,1,-1,-2] ;
idx = find(sign(E)==-1) % Get the sign and get index
idx = find(E<0) % Get by value
for i = 1:length(E)
if sign(E(i)) == -1
fprintf('E is Negative\n')
else
fprintf('E is Positive\n')
end
end

For last positive value
you can use a variable to store the last value
Example:-
E=[3,2,1,-1,-2]
finalpos=-1
for i = 1:5
if ( E<0)
finalpos=E(i-1);
break;
end
end
finalpos

Related

How does the following syntax may be shortened and improved?

Given a 12 x 13 matrix in Matlab, I need to select the row with the greatest value in column 9, every two rows, and create a matrix containing the selected rows. The following piece of code does the job, but I was wondering how this syntax could be improved and shortened.
A = rand(12,13);
a = A(1:2,:);
if a(1,9) > a(2,9)
a = A(1,:);
else
a = A(2,:);
end
b = A(3:4,:);
if b(1,9) > b(2,9)
b = A(3,:);
else
b = A(4,:);
end
c = A(5:6,:);
if c(1,9) > c(2,9)
c = A(5,:);
else
c = A(6,:);
end
d = A(7:8,:);
if d(1,9) > d(2,9)
d = A(7,:);
else
d = A(8,:);
end
e = A(9:10,:);
if e(1,9) > e(2,9)
e = A(9,:);
else
e = A(10,:);
end
f = A(11:12,:);
if f(1,9) > f(2,9)
f = A(11,:);
else
f = A(12,:);
end
SELECTED_A = [a;b;c;d;e;f];
Thank you.
I can provide a way shorter solution, but if you want it fully vectorized, you'll have to wait for someone with a little more proficiency. Here's the code:
A=rand(12,13);
B=zeros(6,13); % preallocate solutionarray
for ii=2:2:12 % loop through every (second) row
[~,ind]=max([A(ii,9),A(ii-1,9)]); % check which element is greater
B(ii/2,:)=A(ii-(ind==2),:); % select corresponding row
end
This will give you an array B with the values you are looking for.
EDIT: There was a little flaw in the code: the condition in row 5 of the code needs to be ind==2 otherwise it will always chose the row with the smaller entry in column 9. Alternatively you could also leave it ind==1 and switch the elements in row 4 i.e. max([A(ii-1,9),A(ii,9)])

How to write a string in replace of a number in MATLAB?

I am trying to categorise the years based on some conditions. If any year has rainfall less than a specific number it will indicate as a dry year. I have tried the following, but it gives me error "In an assignment A(I) = B, the number of elements in B and I must be the same."
The code is
Year_Category = zeros(ny,1);
for i = 1:ny;
if (xy(i)< Lower_Limit)
Year_Category(i) = 'Dry';
elseif (xy(i)> Upper_Limit)
Year_Category(i) = 'Wet';
else
Year_Category(i) = 'Average';
end
end
Any help would be appreciated.
Best regards
You are trying to assign characters to a numeric array. That's why you're getting a dimension mismatch. Each character is a single slot and you can't do that in this case. Use cell arrays instead:
Year_Category = cell(ny,1); %// Change
for i = 1:ny;
if (xy(i)< Lower_Limit)
Year_Category{i} = 'Dry'; %// Change
elseif (xy(i)> Upper_Limit)
Year_Category{i} = 'Wet'; %// Change
else
Year_Category{i} = 'Average'; %// Change
end
end

Saving intermediate variable values of a recursive function

I'm trying to code a function calculating difference quotients. I need to this for polynomial interpolation. Given nodes x = linspace(a,b,n+1), function values at the nodes y = func(x) I want to find the values of difference quotients f[x0], f[x_0,x_1], ..., f[x_0,x_1,...,x_n]. To calculate f[x_0,x_1,...,x_n] I will need f[x_0,x_1,...,x_(n-1)], etc., thus it would be a good idea save the intermediate steps on my way to f[x_0,x_1,...,x_n], so that on my way to f[x_0,x_1,...,x_n] I will save the preceding difference quotients as elements of a vector.
Could someone tell me how to correct my code in order to save appropriate difference quotient values? Here's the code:
function [fx, all_fx] = ilo2(a,b,x,y,fx,all_fx)
if a == b
fx(end+1) = y(a);
if a == 1
all_fx(end+1) = fx(end);
end
return
end
a;
b;
[c, all_fx] = ilo2(a+1,b,x,y,fx,all_fx);
[d, all_fx] = ilo2(a,b-1,x,y,fx,all_fx);
fx(end+1) = (c-d)/(b-a);
if a == 1
all_fx(end+1) = fx(end);
end
end
The difference quotients I need are under 'if a == 1' condition.
Ok, I think I fixed it:
function [all_fx,fx] = ilo(a,b,x,y,all_fx,fx)
if a == b
fx(end+1) = y(a);
if a == 1
all_fx(end+1) = fx(end);
end
return
end
[all_fx,c] = ilo(a+1,b,x,y,all_fx,fx);
[all_fx,d] = ilo(a,b-1,x,y,all_fx,fx);
fx(end+1) = (c-d)/(b-a);
if a == 1
all_fx(end+1) = fx(end);
end
end

How to make If statement with range of numbers - MatLab

I'm trying to generate an action potential of the HH model, and I need to calculate the alphaN rates. However, at a few values, they are 0/0, so I need to use L'hopitals rule. I can't seem to make the script work. Can anyone please help?
How do I do an if statement for a range of numbers? Like:
if Vm == -50:-49
syms Vm;
x = diff((0.01.*(10-(Vm+60))));
y = diff((exp((10-(Vm+60))./10)-1));
alphaN = x./y;
else
alphaN = (0.01.*(10-(Vm+60)))./(exp((10-(Vm+60))./10)-1); % l/ms
betaN = 0.125*exp(-(Vm+60)/80); % 1/ms
end
plot(alphaN,Vm)
However, with the above script, I get matrix doesn't agree. How can I make this work? Hopefully it's just something I'm forgetting.
Thanks for the help!
To test whether Vm is between a and b, you write
if Vm >= a && Vm <= b %# include a and b
To test whether Vm is any integer between a and b
if any(Vm == a:b)
You can use a switch/case construct:
Vm_all = -50:50; %all Vm
for ii = 1:length(Vm)
Vm = Vm_all(ii);
switch Vm
case {-50,-49}
syms Vm;
x = diff((0.01.*(10-(Vm+60))));
y = diff((exp((10-(Vm+60))./10)-1));
alphaN(ii) = x./y;
betaN(ii) = NaN;
otherwise
alphaN(ii) = (0.01.*(10-(Vm+60)))./(exp((10-(Vm+60))./10)-1);
betaN(ii) = 0.125*exp(-(Vm+60)/80);
end
end
This way it doesn't matter if your particular values are in a row or whatever, just type them comma separated.
If you have an array with your exceptions like exc = [-50,-49,-12,42] you can use it as follow for switch/case:
case {exc(:)}

output iteration results from a loop in Matlab

I am trying to use a for loop to make some calculations in a cell array but at the end only the results for the last loop are displayed. I would like Matlab to display the results for all loops. Here there is the code:
slope=[];
time=[];
position= [];
for p=1:max(L) % max L gives the number of result{n}. so if max(L)=6 we have from result{1} to result{6} and therefore 6 final values that i want to get%
a=result{n}(:,1);
b=result{n}(:,2);
end
B = [ones(length(a),1) a] \ b % this is to obtain the slope and intercept of a lin. regresion
slope = B(2)
time = result{n}(end,1)-result{n}(1:1)
position = (slope.*result{n}(end,1)+intercept)-(slope.*result{n}(1:1)+intercept)
At the moment in the output that is what i get:
slope =
4.4089
time =
0.5794
position =
2.5546
This result is correct. However, these values are the ones obtained with result{6} and i need the values previous to this one.
Any help is much appreciated !
Thanks in advance!
You are making a mess with the indexes… It is a bit hard to understand what you did on your code, but it may be something like this (pseudocode since the code you gave does not have the result declared):
slope=zeros(1,max(L)); % Pre allocate zeros, one index for each interation
time=zeros(1,max(L));
position=zeros(1,max(L));
a=zeros(1,max(L));
b=zeros(1,max(L));
for p=1:max(L) % max L gives the number of result{n}. so if max(L)=6 we have from result{1} to result{6} and therefore 6 final values that i want to get%
a(p)=result{p}(:,1);
b(p)=result{p}(:,2);
B = [ones(length(a( p ),1) a( p )] \ b( p) % this is to obtain the slope and intercept of a lin. regresion
slope( p) = B(2)
time( p) = result{p}(end,1)-result{p}(1:1)
position( p) = (slope( p ).*result{p}(end,1)+intercept)-(slope ( p) .*result{p}(1)+intercept)
end
position(6) will get your value, position(5) the previous value.
The easiest way to do this is to remove the ";" for lines that you want printed to the command window. This will display all loop values you need.
for p=1:max(L)
a=result{n}(:,1)
b=result{n}(:,2)
end
Can you do all calculations inside the loop and don't block with ";" instead. If you get a result after coming out of a loop, you will only get the last one.