Why do I get a complex result?

Hi everyone, I've found something that caught my attention, but can't explain or maybe I'm missing something. This is the code:
Lmin = 3;
L = zeros(21,1); L(1) = Lmin;
for i = 1 : 20
delta(i) = (- 1 - 1.5 * dt)^2 - 4 * 0.12 * dt * (L(i) + 4.89 * dt)
num(i+1) = - (- 1 - 1.5 * dt) + sqrt( delta(i) )
den(i+1) = dt * 2 * 0.12
L(i+1) = num(i+1) / den(i+1)
end
Practically everything is okay if num(i+1) = - (- 1 - 1.5 * dt) - sqrt( delta(i) ) Note I just changed a sign and even though it is outside the square root, seems it matters. However the starngest thing is this. If you run the code above (the whole for loop with the "+" to get the num), the code gives back complex numbers. However,if:
  1. Remove the last equation to calculate L, you can see that there is no complex number among the above variables
  2. Simply removing the 0.12 from the "den equation" gives a real numberSo, try the above code and the followings two and you will understand what I mean:
Lmin = 3;
L = zeros(21,1); L(1) = Lmin;
for i = 1 : 20
delta(i) = (- 1 - 1.5 * dt)^2 - 4 * 0.12 * dt * (L(i) + 4.89 * dt)
num(i+1) = - (- 1 - 1.5 * dt) + sqrt( delta(i) )
den(i+1) = dt * 2 * 0.12
%L(i+1) = num(i+1) / den(i+1)
end
and
Lmin = 3;
L = zeros(21,1); L(1) = Lmin;
for i = 1 : 20
delta(i) = (- 1 - 1.5 * dt)^2 - 4 * 0.12 * dt * (L(i) + 4.89 * dt)
num(i+1) = - (- 1 - 1.5 * dt) + sqrt( delta(i) )
den(i+1) = dt * 2
L(i+1) = num(i+1) / den(i+1)
end
Now my question is: why is this happening? Why this denominator is affecting previous calculations?

2 Commenti

Erg
Erg il 29 Nov 2017
Sorry, just noticed I didn't include dt = 0.63
Jan
Jan il 29 Nov 2017
Modificato: Jan il 29 Nov 2017
This is a tricky puzzler. You mention, that you have changed a sign anywhere in the 3 almost equal code snippets. I've searched a little bit and found the difference "dt * 2 * 0.12" and "dt * 2". But I did not find the mentioned change of the "+".
Of course commenting "L(i+1) = num(i+1) / den(i+1)" matters, because then the value of "(L(i) + 4.89 * dt)" is effected in the following iteration.
Finally the observed behavior is exactly what is expected. See Stephen's answer. In consequence this question is not meaningful:
Why this denominator is affecting previous calculations?
Perhaps using the debugger and processing the code line by line helps to understand, what's going on.
By the way: The simpler the code, the easier it is to understand. Therefore I'd write:
delta(i) = (1 + 1.5 * dt)^2 - 0.48 * dt * (L(i) + 4.89 * dt);
num(i+1) = (1 + 1.5 * dt) + sqrt(delta(i));
Or maybe:
delta(i) = 1 + (3 - 0.48* L(i)) * dt - 0.0972 * dt ^ 2;

Accedi per commentare.

 Risposta accettata

Stephen23
Stephen23 il 29 Nov 2017
Modificato: Stephen23 il 29 Nov 2017
On the second iteration you generate a negative delta value. Then clearly the sqrt of a negative value is complex. You save this complex value into variable delta which forces MATLAB to make that variable complex. Thus all following calculations use those complex values as inputs, giving complex outputs.
What do you expect the square root of a negative value to give you?
Complex values are not stored element-wise, but either the entire variable is complex, or it is not. So when you force the second element of delta to be complex you force all elements of delta to be complex (with default imaginary part zero). This is because MATLAB does not store this:
V = [5,2+3i]
as a vector of one non-complex and one complex number. It stores one complex vector V, where the first element has zero imaginary part. Try it and see what happens:
>> V = [5,2+3i]
V =
5 + 0i 2 + 3i

5 Commenti

Erg's "Answer" moved here:
Thanks for the quick reply! I totally agree with what you said. If delta is negative, the complex number is a must. But, if you check the second iteration i proposed(which is exactly like the first one, I'm just not considering the last equation to calculate L), there is no negative delta. Why is that? Am I missing something? Try to run this one:
dt =0.63
Lmin = 3;
L = zeros(21,1); L(1) = Lmin;
for i = 1 : 20
delta(i) = (- 1 - 1.5 * dt)^2 - 4 * 0.12 * dt * (L(i) + 4.89 * dt)
num(i+1) = - (- 1 - 1.5 * dt) + sqrt( delta(i) )
den(i+1) = dt * 2 * 0.12
%L(i+1) = num(i+1) / den(i+1)
end
Stephen23
Stephen23 il 29 Nov 2017
Modificato: Stephen23 il 29 Nov 2017
You wrote a loop where each iteration calculates the next iteration's value of L, which is then used in the calculation. If you change how you calculate L why would you expect to get the same results?
Unfortunately your very generous spacing policy makes the code harder to read and understand. But once we group the terms together you will see why this happens:
t1 = (- 1 - 1.5 * dt)^2
t2 = 4 * 0.12 * dt * (L(i) + 4.89 * dt)
delta(i) = t1 - t2;
To get a negative delta the second term t2 must be greater than the first term t1. Lets have a look:
% full code:
t1 = 3.7830
t2 = 1.8388
t1 = 3.7830
t2 = 7.6103
t1 = 3.7830
t2 = 4.8216 + 3.9127i
t1 = 3.7830
t2 = 7.2750 - 3.1896i
etc
% No L calculation:
t1 = 3.7830
t2 = 1.8388
t1 = 3.7830
t2 = 0.93160
t1 = 3.7830
t2 = 0.93160
t1 = 3.7830
t2 = 0.93160
etc
So when you change how you calculate the L value then it clearly should change the output value of the next iteration. That is how you wrote the code.
"Why is that?"
Because that is what you wrote it to do.
"Am I missing something?"
Look at the L values on each iteration.
Erg
Erg il 29 Nov 2017
My bad, yes yes you are totally right. Better if I get a break ahah don't know how I couldn't see that. Thank you!
Jan
Jan il 29 Nov 2017
@Erg: In many cases debugging is supported by a cup of coffee.
Erg
Erg il 29 Nov 2017
@Jan yep i think it may help lol. Thanks for your answer as well!

Accedi per commentare.

Più risposte (0)

Categorie

Richiesto:

Erg
il 29 Nov 2017

Commentato:

Erg
il 29 Nov 2017

Community Treasure Hunt

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

Start Hunting!

Translated by