If statement is not correctly operating

Dear Matlab experts,
I have a simple if statement to execute, however is not responding how I am expecting in a relaxation function. In the attached matlab code, I want my code to respond in two steps:
  1. Firstly, initialize some internal variables to ZEROS during first elements of X-data vector, i.e., lambda(1,1) and lambda(1,2): The value of these variables remains ZEROS until a subsequent if statement is fulfilled.
for r = 1
if (lambda(r,1) == lambda(1,1)) && (lambda(r,2) == lambda(1,2))
Dmat = 0.0;
Dmat_ant = 0.0;
Thetam = 0.0;
Thetam_ant = 0.0;
end
end
2. Secondly, I need to compute a function value PK2 which is dependent on an internal variable Dmat = [0, 1] and is calculated fulfilling a if statement:
if Taum_t < Taum_max
PK2(:,1) = PK2_peak1;
PK2(:,2) = PK2_peak2;
PK2(:,3) = PK2_peak3;
else
Taum_max = Taum_t;
Amat = (gdm./S0dm.^2 - 0.5).^(-1);
Dmat = 1 - (S0dm./Taum_t).* exp(Amat.*(1 - (Taum_t./S0dm)));
delDmat = Dmat - Dmat_ant;
Thetam = Thetam_ant + WbarISO.* delDmat;
Dmat_ant = Dmat;
Thetam_ant = Thetam;
PK2(:,1) = (1 - Dmat).*PK2_peak1;
PK2(:,2) = (1 - Dmat).*PK2_peak2;
PK2(:,3) = (1 - Dmat).*PK2_peak3;
end
It means, Dmat is calculated only when Taum_t >= Taum_max, for other cases, Dmat = 0. It applies the same for Dmat_ant, Thetam and Thetam_ant.
Running the existing matlab code gives a continusouly increasing PK2 value which does not fit to the Y-data. In addition, commenting the if statement
%if Taum_t < Taum_max
% PK2(:,1) = PK2_peak1;
% PK2(:,2) = PK2_peak2;
% PK2(:,3) = PK2_peak3;
%else
gives the fitted curve towards X-data vs Y-data plot which is again not correct because Dmat, Dmat_ant, Thetam and Thetam_ant are not initialized to ZEROS at the beginning of the calculation.
Can anyone please help me to fix the issue? Thank you very much in advance.

7 Comments

why do you have a for loop over a single element? (for r = 1)
With r==1 the expression
(lambda(r,1) == lambda(1,1)) && (lambda(r,2) == lambda(1,2))
is always true. However, == doesn't go well together with double because of floating point errors.
@Sindar and per Isakson, I wasn't sure about the fact it would be erroneous. Nevertheless, I changed the for loop over "r = 1:n" (list of the array) element, which obviously gives the ZEROS again. But how can I still fix the if statement to calculate the variables when else statement is valid?
From what I can see, it's not an issue with the if Taum_t < Taum_max statement. My suggestion is to go into debug mode and step through one line at a time, keeping track of the variable values.
Also, you seem to have completely missed both our points about the r-loop, so I'll rephrase
  • Why have a loop at all when you only do one iteration?
  • Why loop through more iterations when the first one should do everything you need, and later iterations either do nothing or repeat the same action?
  • Checking equality for doubles is risky. There are other strategies which are safer
  • Why are you even checking for equality when you know the items are equal?
This has the intended effect, no loops no ifs:
Dmat = 0.0;
Dmat_ant = 0.0;
Thetam = 0.0;
Thetam_ant = 0.0;
@Sindar, I understood most of your suggestions which were undoubtely correct. Previous for loop with if statement and an additional inequal if statement were redundant in my previous code. My apologies for my little knowledge.
Extending the single check option, let me simply my problem. For an array of lambda(:,1) as provided in Matlab snippet code, Dfib is given as:
I understand below code is not fully correct: for a certain value of S0d, Tau_t and A_fib, Dfib is computed also at lambda(:,1) <= 1.6 which had to be zero. How to code the above formulation? [Note: if any(lambda(:,1) <= 1.6) does not work either. Also, isn't an inequality check mandatory in such cases?]
lambda(:,1) = [1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2];
if lambda(:,1) <= 1.6
Dfib = 0.0;
else
Dfib = 1 - (S0d./Tau_t).* exp(Afib.*(1 - (Tau_t./S0d)));
end
% Incorrectly computed values of Dfib, where first four elements should have been zeros for
% lambda <= 1.6
Dfib = [0.4206, 0.6489, 0.7775, 0.8568, 0.9079, 0.9419, 0.9645, 0.9794, 0.9889, 0.9946]
For this particular point, you can easily loop through:
lambda(:,1) = [1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2];
% loop over rows of lambda
for ind=1:size(lambda,1)
if lambda(ind,1) <= 1.6
Dfib(ind) = 0.0;
else
% unclear what variables are vectors
% Dfib(ind) = 1 - (S0d./Tau_t).* exp(Afib.*(1 - (Tau_t./S0d)));
Dfib(ind) = 1 - (S0d(ind)./Tau_t(ind)).* exp(Afib(ind).*(1 - (Tau_t(ind)./S0d(ind))));
end
end
or without the loop:
Dfib=zeros(size(lambda,1),1);
idx = (lambda(:,1) <= 1.6);
Dfib(idx) = 1 - (S0d(idx)./Tau_t(idx)).* exp(Afib(idx).*(1 - (Tau_t(idx)./S0d(idx))));
For your original code, the question is probably what portions of the code need to be in the loop. Does it run through the whole code for each element of lambda? Or, does it operate on a vector of Dfib?
Thank you Sindar for the explanation, for loop over lambda and the followed if statement gave me what I was looking for. The unclear variables you mentioned were all user-defined scalars except . I could have asked you the simple formulation instead of confusing long paragraphs.

Answers (0)

This question is closed.

Asked:

on 22 Oct 2020

Closed:

on 20 Aug 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!