If statement in a Loop - matlab

I want my code to check if my 'e' components are in range of +,- 0.72 to +,- 0.73 to store the magnitude of Delta_theta and M in a vector for Plot. But I don't really know what is wrong in the last if statement. I just tried to store the amount of M that satisfies this condition in another matrix 'G' and plot it against delta theta, but it doesn't work either.
With kind regards.
I am sure the second and all other statements are correct, I just need help for the last one, thanks
Problem is Here
if e(Idx_1,Idx_2) >=0.072 && e(Idx_1,Idx_2) < 0.077 || e(Idx_1,Idx_2) <=-0.072 && e(Idx_1,Idx_2) > -0.077;
G=M;
end
clear all
clc
%% Constants
B=1.2;
H=0.35;
R=2.93;
b=1;
h=0.24;
d_c=0.06;
D_s=0.03;
d_s=0.4;
r_s=0.015;
N_s=2;
E_s=200e9;
f_y=500e6;
E_c=43.6e9;
v_c=0.24;
f_c=35.5e6;
F=1.9;
A_s=pi*r_s^2;
e=0.3*h;
%% Operator
Idx_1 = 0;
for delta_theta =-40*10^-3:0.05*10^-3:40*10^-3
alpha_e=0;
alpha_p=0;
beta_e=0;
beta_p=0;
r_b=0;
r_s=0;
r_e=0;
Idx_1 = Idx_1 + 1;
Idx_2 = 0;
delta_thetavalue(Idx_1)=delta_theta;
A=r_s-(f_y*d_s/(E_s*delta_theta));
for delta_l=-10*10^-2:0.05*10^-2:10*10^-2
Idx_2 = Idx_2 + 1;
delta_lvalue(Idx_2)=delta_l;
r_0=R-(delta_l/delta_theta);
r_1=R-((1/delta_theta)*(delta_l+(F*f_c*d_c)/E_c));
if delta_theta >=0
r_op=R+(h/2);
r_cl=R-(h/2);
if r_0 >= r_op && r_1<=r_cl
alpha_e=1;
r_b=r_op;
r_e=r_cl;
elseif r_0 >=r_op && r_cl<r_1 && r_1<r_op
alpha_e=1;
alpha_p=1;
r_b=r_op;
r_e=r_1;
elseif r_0 >=r_op && r_1>=r_op
alpha_p=1;
r_b=r_op;
r_e=r_op;
elseif r_s<r_0 && r_0<r_op && r_1<=r_cl
alpha_e=1;
r_b=r_0;
r_e=r_cl;
elseif r_s<r_0 && r_0<r_op && r_1>r_cl
alpha_e=1;
alpha_p=1;
r_b=r_0;
r_e=r_1;
elseif A<r_0 && r_cl<r_0 && r_0<=r_s && r_1<=r_cl
alpha_e=1;
beta_e=1;
r_b=r_0;
r_e=r_cl;
elseif A<r_0 && r_cl<r_0 && r_0<=r_s && r_1>r_cl
alpha_e=1;
alpha_p=1;
beta_e=1;
r_b=r_0;
r_e=r_1;
elseif A>=r_0 && r_0>r_cl && r_1<=r_cl
alpha_e=1;
beta_p=1;
r_b=r_0;
r_e=r_cl;
elseif A>=r_0 && r_0>r_cl && r_1>r_cl
alpha_e=1;
alpha_p=1;
beta_p=1;
r_b=r_0;
r_e=r_1;
elseif r_0 <= r_cl
r_b=r_cl;
r_e=r_cl;
end
else
r_op=R-(h/2);
r_cl=R+(h/2);
if r_0 <= r_op && r_1 >= r_cl
alpha_e=1;
r_b=r_op;
r_e=r_cl;
elseif r_0 <=r_op && r_1>r_op && r_cl>r_1
alpha_e=1;
alpha_p=1;
r_b=r_op;
r_e=r_1;
elseif r_0 <=r_op && r_1<=r_op
alpha_p=1;
r_b=r_op;
r_e=r_op;
elseif r_s>r_0 && r_0>r_op && r_1>=r_cl
alpha_e=1;
r_b=r_0;
r_e=r_cl;
elseif r_s>r_0 && r_0>r_op && r_1<r_cl
alpha_e=1;
alpha_p=1;
r_b=r_0;
r_e=r_1;
elseif A>r_0 && r_cl>r_0 && r_0>=r_s && r_1>=r_cl
alpha_e=1;
beta_e=1;
r_b=r_0;
r_e=r_cl;
elseif A>r_0 && r_cl>r_0 && r_0>=r_s && r_1<r_cl
alpha_e=1;
alpha_p=1;
beta_e=1;
r_b=r_0;
r_e=r_1;
elseif A<=r_0 && r_0<r_cl && r_1>r_cl
alpha_e=1;
beta_p=1;
r_b=r_0;
r_e=r_cl;
elseif A<=r_0 && r_0<r_cl && r_1<=r_cl
alpha_e=1;
alpha_p=1;
beta_p=1;
r_b=r_0;
r_e=r_1;
elseif r_0 >= r_cl
r_b=r_cl;
r_e=r_cl;
end
end
M(Idx_1,Idx_2)=alpha_e*(E_c*b/d_c)*((delta_l/2)*((r_b-R)^2-(r_e-R)^2)+(delta_theta/3)*((r_b-R)^3-(r_e-R)^3))+alpha_p*(-F*f_c*b*abs(r_cl-r_e)*(((r_cl+r_e)/2)-R))+beta_e*E_s*A_s*((delta_l/d_s)+(delta_theta/d_s)*(r_s-R))*(r_s-R)+beta_p*f_y*A_s*(r_s-R);
N(Idx_1,Idx_2)=alpha_e*(E_c*b/d_c)*(delta_l*(r_e-r_b)+(delta_theta/2)*((r_e-R)^2-(r_b-R)^2))+alpha_p*(-F*f_c*b*abs(r_cl-r_e))+beta_e*E_s*A_s*((delta_l/d_s)+(delta_theta/d_s)*(r_s-R))+beta_p*f_y*A_s;
e=M./N;
end
if e(Idx_1,Idx_2) >=0.072 && e(Idx_1,Idx_2) < 0.077 || e(Idx_1,Idx_2) <=-0.072 && e(Idx_1,Idx_2) > -0.077;
G=M;
end
end
plot(delta_thetavalue,G)

We cannot check how your function e works but have you tried wrapping your conditions in parenthesis so it understand that it need to check them in pair?
if (e(Idx_1,Idx_2) >=0.072 && e(Idx_1,Idx_2) < 0.077) || (e(Idx_1,Idx_2) <=-0.072 && e(Idx_1,Idx_2) > -0.077);
also it could be easier to debug if you evaluate it once
evaluation = e(Idx_1,Idx_2); // you can print or anything to check the value before the if expression
if (evaluation >=0.072 && evaluation < 0.077) || (evaluation <=-0.072 && evaluation > -0.077);

Since you specifically ask for help for the last if statement, I can tell you there is nothing wrong with it. It appears your "e" function might have some bugs. Here is a dummy code snippet for you to play with the eVal which is a placeholder for your e(arg1, arg2) function. You should narrow this down and make sure where the error is by using the built in debugger.
clc;
eVal = 0.076;
G = zeros(3);
M = eye(3);
if eVal >= 0.072 && eVal < 0.077 || eVal <= -0.072 && eVal > -0.077;
G = M;
end
disp(G); % Should return eye(3) if the statement is true

I solved this problem like this :
t=0;
for Idx_1=1:1601 ;
for Idx_2=1:401;
if (e(Idx_1,Idx_2) >=0.072 && e(Idx_1,Idx_2) < 0.073) || (e(Idx_1,Idx_2) <=-0.072 && e(Idx_1,Idx_2) > -0.073);
t=t+1;
dt(t)=delta_thetavalue(Idx_1);
mf(t)=M(Idx_1,Idx_2);
end
end
end
plot(dt,mf)

Related

Test for scalar function inputs is failing

Despite using isscalar, isinteger... the result after running is still true, I still had this test which is incorrect and in relation with Scalar values.
My program:
function valid = valid_date(year, month, day)
[y1 y2] = size(year);
[m1 m2] = size(month);
[d1 d2] = size(day);
if (mod(year,4)==0 && mod(year,100)~=0) || mod(year,400)==0
is_leap_year = 1;
else
is_leap_year = 0;
end
if ~(y1==y2==d1==d2==m1==m2==1)
valid = false;
elseif any(month == [1, 3, 5, 7, 8, 10, 12])
valid = (day >0 && day <= 31)
elseif any(month == [4, 6, 9, 11])
valid = day >0 && day <= 30;
elseif month == 2 && is_leap_year == 1
valid = (day >0 && day <=29);
elseif month == 2 && is_leap_year == 0
valid = (day >0 && day <=28);
else
valid = false;
end
end
The result after submitting my program, all tests are passed except the one related to scalar values:
Why did my program fail on the non-scalar test?
The way you're checking for scalars is really not well defined.
~(y1==y2==d1==d2==m1==m2==1)
This chained equivalence check is not the same as checking if all of your variables are equal to 1, consider the following counter-example:
1==0==0==1 % Output: 1
In this case none of your comparison variables should be 0, so you might skirt this issue, but it's still best to avoid it. You're also contending with floating point comparisons which are prone to issues.
You should use isscalar, you say you tried it but didn't show how. Something like this should work:
function valid = valid_date(year, month, day)
if ~( isscalar(year) && isscalar(month) && isscalar(day) )
valid = false;
return
end
% ... other code now we know inputs are scalar
end
Thank you so much #Wolfie. The problem is solved.
I used what you told me about and put it at the beginning of my function.
I show you guys the code, in case you had the same error:
function valid = valid_date(year, month, day)
if ~(isscalar(year) && isscalar(month) && isscalar(day))
valid = false;
return
end
if ((mod(year,4)==0 && mod(year,100)~=0) || mod(year,400)==0)
is_leap_year = 1;
else
is_leap_year = 0;
end
if any(month == [1, 3, 5, 7, 8, 10, 12])
valid = (day >0 && day <= 31);
elseif any(month == [4, 6, 9, 11])
valid = day >0 && day <= 30;
elseif (month == 2 && is_leap_year == 1)
valid = (day >0 && day <=29);
elseif (month == 2 && is_leap_year == 0)
valid = (day >0 && day <=28);
else
valid = false;
end
end
Yaaay all the tests are passed lhamdullah!

Is it possible to vectorize a function script in matlab?

If I have explicit function, I can vectorise it. How about if I have a function script? For example, if I have a script Fun.m such that Fun(x,y,z) gives a value and I want to compute x=[1,2,3] and y=[4,5] (i.e. (1,4), (1,5), (2,4), (2,5),(3,4), (3,5)) when z=10, are there any possible way to do it apart from using for-loop? Indeed, I may need to compute x,y for a long vector. I want to use bsxfun(#(x,y)Fun(x,y,10),[1,2,3],[4,5]') but it does not work. It says matrix dimension does not match.
Let me post the function Fun.m I have:
function density=HittingDensityOUlevel0(beta,r0,sigma,lambda,t0,i,p,MinOrMax)
g=zeros(1,i);
g(:,1)=-1.*MinOrMax.*2.*Integrand(r0,sigma,lambda,t0+p,t0,beta,r0);
for k=2:size(g,2)
Sum=0;
weight=zeros(1,k-1);
for m=1:k-1
R1=mod(k,2); Q1=floor(k./2);
R2=mod(m,2); Q2=floor(m./2);
if R1==0 && R2==1 && Q2<=Q1-1
weight(:,m)=4./3;
elseif R1==0 && R2==0 && Q2<=Q1-2
weight(:,m)=2./3;
elseif R1==1 && R2==1 && Q2<=Q1-2
weight(:,m)=4./3;
elseif R1==1 && R2==0 && Q2<=Q1-3 && Q1>=3
weight(:,m)=2./3;
elseif R1==1 && R2==0 && m==2*(Q1-1)
weight(:,m)=17./24;
elseif R1==1 && m==2*Q1-1 && Q1>=1
weight(:,m)=9./8;
elseif R1==1 && m==2*Q1 && Q1>=1
weight(:,m)=9./8;
end
end
TimeTicker=(t0+p):p:(t0+(k-1)*p);
Sum=Sum+2.*p.*sum(weight.*g(:,1:(k-1)).*arrayfun(#(t)Integrand(r0,sigma,lambda,t0+k.*p,t,beta,beta),TimeTicker));
g(:,k)=-1.*MinOrMax.*2.*...
Integrand(r0,sigma,lambda,t0+k.*p,t0,beta,r0)+MinOrMax.*Sum;
end
density=g(:,end);
function ret=Integrand(r0,sigma,lambda,t,tau,x,y)
ret=(lambda.*r0.*exp(-lambda.*t)./2+...
(x-r0.*exp(-lambda.*t))./2.*lambda.*cosh(lambda.*(tau-t))./sinh(lambda.*(tau-t))-...
(y-r0.*exp(-lambda.*tau))./2.*lambda./sinh(lambda.*(tau-t))).*...
...
(1./sqrt(pi.*sigma.^2./lambda.*(1-exp(-2.*lambda.*(t-tau))))).*...
...
(exp(-((x-r0.*exp(-lambda.*t)-exp(-lambda.*(t-tau)).*(y-r0.*exp(-lambda.*tau))).^2)./...
(sigma.^2./lambda.*(1-exp(-2.*lambda.*(t-tau))))));
I want to vectorize this Fun with (for example) t0=[1,2,3] and r0=[4,5]. But it does not work.
Use meshgrid to generate all possible pairs of inputs to your function.
[tt0,rr0] = meshgrid([1,2,3],[4,5])
so that tt0 = [1,2,3,1,2,3] and rr0 = [4,4,4,5,5,5]
Then pass that to bsxfun.

Long and detailed AND,OR conditional IF statements on MATLAB

Could you please tell me what my mistake is on the following code:
if ((i>156-9 && i<156+9) && (j>406-9 && j<406+9)) || ((i>684-11 && i<684+11) && (j>274-11 && j<274+11)) || ((i>1066-15 && i<1066+15) && (j>67-15 && j<67+15)) || ((i>1559-15 && i<1559+15) && (j>867-15 && j<867+15)) || ((i>1082-18 && i<1082+18) && (j>740-18 && j<740+18))
plot(j, i, 'r+', 'MarkerSize', 7, 'LineWidth', 5);
end
I'd like to use an if statement which obeys to get in the expression if one of these conditions are fulfilled:
((i>156-9 && i<156+9) && (j>406-9 && j<406+9)) OR
((i>684-11 && i<684+11) && (j>274-11 && j<274+11)) OR
((i>1066-15 && i<1066+15) && (j>67-15 && j<67+15)) OR
((i>1559-15 && i<1559+15) && (j>867-15 && j<867+15)) OR
((i>1082-18 && i<1082+18) && (j>740-18 && j<740+18))
Thanks in advance...
Regards.
I have used your expression in the if as is and used this for this little piece of code.
clc; A=[];
for i=1:2000
for j=1:2000
if ((i>156-9 && i<156+9) && (j>406-9 && j<406+9)) || ((i>684-11 && i<684+11) && (j>274-11 && j<274+11)) || ((i>1066-15 && i<1066+15) && (j>67-15 && j<67+15)) || ((i>1559-15 && i<1559+15) && (j>867-15 && j<867+15)) || ((i>1082-18 && i<1082+18) && (j>740-18 && j<740+18))
A = [A, num2str(i),' ',num2str(j), char(10)];
end
end
end
display(A);
It works for me.

Last elseif statement does not execute

My last elseif statement does not execute even if the conditions are met:
Currency_Exchanage != 'Select...' and all other variables (ETF_Exchanage, Index_Exchanage and Stock_Exchanage) = 'Select...'
Here is the section of code that I am concerned about:
if (strcmp(ETF_Exchanage,'Select...') == 1) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1)
if db == 1 && uni == 1
tickers = gnr_bloomberg; % Analsise Bloomberg natural resources
nrm=1;
elseif db == 1 && uni == 2
tickers = all_bloomberg; % Analsise Bloomberg all
nrm=1;
elseif db == 2 && uni == 1
tickers = gnr_yahoo; % Analsise Yahoo natural resources
nrm=1;
elseif db == 2 && uni == 2
tickers = all_yahoo; % Analsise Yahoo all
nrm=1;
end
else
%Yahoo inputs
if (strcmp(ETF_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from ETF
tickers = ETF_Yahoo(:,1);
Exchanges = ETF_Yahoo(:,2);
Exchange = ETF_Exchanage;
db=2; %Yahoo Selection
elseif (strcmp(Index_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(ETF_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from Index
tickers = Index_Yahoo(:,1);
Exchanges = Index_Yahoo(:,2);
Exchange = Index_Exchanage;
db=2;
elseif (strcmp(Stock_Exchanage,'Select...') == 0) && (strcmp(ETF_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from Stock
tickers = Stock_Yahoo(:,1);
Exchanges = Stock_Yahoo(:,2);
Exchange = Stock_Exchanage;
db=2;
elseif (strcmp(Currency_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(ETF_Exchanage,'Select...') == 1); %Choose exhanges from Currency
tickers = Currency_Yahoo(:,1);
Exchanges = Currency_Yahoo(:,2);
Exchange = Currency_Exchanage;
db=2;
else
msg = 'Error occurred.\Only one Yahoo input menue must be used!';
error(msg)
end
end
Any Help would be much appropriated, I can't see where I'm going wrong here. I am using Matlab 2013a.
Put a breakpoint at the elseif statement in question and then check in the command window what your condition evaluates to.
If it does not evaluate like expected, check what the individual terms evaluate to.
It is important to actually test what the conditions evaluate to in matlab, rather than only visually comparing the string values.
Usually by that point you should get a rough idea what is wrong.
However in your case we can't do these steps for you because something is off. Your code condensed to the more reasonable minimal example
if 1 && 1 && 1...
1;
disp('I was here')
end
does not even execute in R2014a since the interpreter complains about '...' being an unexpected matlab expression.

Nyquist criterion - undefined variable in algorithm

I write an algorithm that checks the stability of the closed system of the Nyquist criterion (http://en.wikipedia.org/wiki/Nyquist_stability_criterion)
function answear=stability(re,im)
%% Function check stability of system
%re is real part of transmitation
%im is imagine part of transmitation
%% Check number of vectors elements
re(end +1:5) = 0;
im(end +1:5) = 0;
if( length(re) > length(im))
root = length(re);
else
root = length(im);
end
for w=1:root
tran(w) = re(1) + re(2)*w.^1 + re(3)*w.^2 + re(4)*w.^3 + re(5)*w.^4 +1i*(...
im(1) + im(2)*w.^1 + im(3)*w.^2 + im(4)*w.^3 +im(5)*w.^4);
end
%% Algorithm
switch root
case 0
exist('Write nonzero numbers', 'var')
case 1
for w=1:length(w)
if( real(tran(w)) > 0 && imag(tran(w)) > 0)
answear=1;
else
answear=0;
end
end
case 2
for w=1:length(w)
if( real(tran(w)) > 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) > 0)
answear=1;
else
answear=0;
end
end
end
case 3
for w=1:length(w)
if( real(tran(w)) > 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) < 0)
answear=1;
else
answear=0;
end
end
end
end
case 4
for w=1:length(w)
if( real(tran(w)) > 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) < 0)
if( real(tran(w)) > 0 && imag(tran(w)) < 0)
answear=1;
else
answear=0;
end
end
end
end
end
end
%% Answear
if answear==1
disp('System unstable')
else
disp('System stable')
end
plot(real(tran),imag(tran))
grid on
end
Function returns
Undefined function or variable "answear".
Error in stability (line 87) if answear==1
So the algorithm is badly written?
Your code could use a lot of cleanup:
Instead of an if-statement such as this one:
if( real(tran(w)) > 0 && imag(tran(w)) > 0)
answear=1;
else
answear=0;
end
you could write a boolean assignment:
answear = real(tran(w)) > 0 & imag(tran(w)) > 0);
Why do you have three (almost) identical nested if-statements at all?
if( real(tran(w)) > 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) > 0)
if( real(tran(w)) < 0 && imag(tran(w)) < 0)
First of all, you could replace everything with one if-statement. But what are you actually testing with this? It seems that those nested if statements are never executed. For instance, real(tran(w)) cannot be both positive and negative at the same time (unless it is a vector you are working on, in which case you shouldn't be using the operator &&).
Also, this is probably your code triggers the error regarding variable answear. Accessing it is impossible since it hasn't been assigned a value (none of the if-statements have been executed).
What is tran, and what is w? Are they global variables? If they are, pass them as input parameters. Your function is probably poorly designed if it relies on external states and variables.
I haven't actually run your code, but these suggestions should make it easier for you to debug it.
P.S:
Please fix the annoying spelling error (it is "answer" and not "answear") :)