Why is MatLab making a real number complex? - matlab

I'm a little confused by what MatLab is doing here ... why does multiplying a real expression by a real constant suddenly make it complex?
x = -1.1451e+02 - 1.1317e+02i;
x*conj(x)
>> 2.5920e+04
10*x*conj(x)
>> 2.5920e+05 - 1.4552e-11i

It is definitely a rounding error. Note that if you add parentheses, your results change:
>> 10 * (x * conj(x));
ans =
2.5920e+05

Related

Why does Matlab not evaluate a symbolic expression when using subs()?

This is the code along with the output.
>> syms x
>> y=-(x-2*sin(x))/(1-2*cos(x))
y =
(x - 2*sin(x))/(2*cos(x) - 1)
>> x=1.9
x =
1.9000
>> subs(y)
ans =
-(2*sin(19/10) - 19/10)/(2*cos(19/10) - 1)
I can't figure out why this absurd answer is coming. I am not able to fix it.
So far I have tried taking y also as a symbolic variable and using int(ans) , with no success. I have also tried storing ans in a non-symbolic variable, but the same output shows up every time.
You need to use double on the result to evaluate the symbolic expression and get a numeric value:
>> out = double(subs(y))
out =
-0.004494059516242
subs will substitute the value in your expression, but it will stay symbolic and will not be computed. In order to get the value numerically you need eval instead of subs.
eval(subs(...)) also work. I don't know what is better to use eval either double, my teacher uses double

How to compute an exponent in matlab without getting inf even with vpa or sym?

i have this exp function in matlab
a1=(exp(-beta0*abs(z-zaks)));
b1=(ohmi*exp(-2*beta0*H)*exp(-beta0*(z+zaks)))
c1=(ohmu*exp(beta0*(z+zaks)))
f1=(ohmu*ohmi*exp(-2*beta0*H)*exp(beta0*abs(z-zaks)))
g1=2*beta0*(1-(ohmu*ohmi*exp(-2*beta0*H)))
h1=(a1+b1+exp(c1)+f1)
j1=exp(h1)
gpm=j1/g1
with
beta0=1.411608078945960e+20 + 8.949434210398852e-26i
betai=[1.411608078945960e+20 + 8.949434210398852e-26i 1.411608078945960e+20 + 1.398349095374821e-26i 1.411608078945960e+20 + 1.398349095374821e-27i 1.411608078945960e+20 + 1.398349095374821e-26i]
ohmi=[9.803212783111246e-92 + 2.674639380309578e-46i 2.428723887707741e-93 + 4.457732300515962e-47i -2.428723887707741e-93 - 4.457732300515962e-47i;1.411608078945960e+20 + 1.398349095374821e-26i]
ohmu=1.004853842833425e-91 + 3.169942969255795e-46i
z=zaks=4950
H=5000
and it return to be inf
even if i had using vpa or sym in it
what should go wrong with this?
It also depends on whether you used vpa correctly:
>> vpa(1e400)
ans =
Inf
>> vpa('1e400')
ans =
1.0e400
So you always have to prevent matlab from evaluating something large/small before using vpa. Now, this doesn't solve your problem, since
>> vpa(exp(1.3975e+024 +8.8599e-022*i))
ans =
Inf + Inf*i
>> vpa('exp(1.3975e+024 +8.8599e-022*i)')
ans =
Inf + Inf*i
>> exp(vpa('1.3975e+024 +8.8599e-022*i'))
ans =
RD_INF + RD_INF*i
so regardless of the approach you use, you will get infinity for all intents and purposes.
Why is that, you might ask? Consider that
exp(710)
ans =
Inf
Now, your number is roughly equal to
exp(1397500000000000000000000)
or
10^606926538459794441764864
or
1e606926538459794441764864
Of course I ignored a teeny-tiny imaginary part, but that doesn't change much. You do realise that it's a very big number, right?
So, as #BillBokeey has already commented: what do you plan to do with this number? Your best options are probably doing anything you want on paper first, and reach a result that can be handled by a computer.

Solve equation with exponential term

I have the equation 1 = ((π r2)n) / n! ∙ e(-π r2)
I want to solve it using MATLAB. Is the following the correct code for doing this? The answer isn't clear to me.
n= 500;
A= 1000000;
d= n / A;
f= factorial( n );
solve (' 1 = ( d * pi * r^2 )^n / f . exp(- d * pi * r^2) ' , 'r')
The answer I get is:
Warning: The solutions are parametrized by the symbols:
k = Z_ intersect Dom::Interval([-(PI/2 -
Im(log(`fexp(-PI*d*r^2)`)/n)/2)/(PI*Re(1/n))], (PI/2 +
Im(log(`fexp(-PI*d*r^2)`)/n)/2)/(PI*Re(1/n)))
> In solve at 190
ans =
(fexp(-PI*d*r^2)^(1/n))^(1/2)/(pi^(1/2)*d^(1/2)*exp((pi*k*(2*i))/n)^(1/2))
-(fexp(-PI*d*r^2)^(1/n))^(1/2)/(pi^(1/2)*d^(1/2)*exp((pi*k*(2*i))/n)^(1/2))
You have several issues with your code.
1. First, you're evaluating some parts in floating-point. This isn't always bad as long as you know the solution will be exact. However, factorial(500) overflows to Inf. In fact, for factorial, anything bigger than 170 will overflow and any input bigger than 21 is potentially inexact because the result will be larger than flintmax. This calculation should be preformed symbolically via sym/factorial:
n = sym(500);
f = factorial(n);
which returns an integer approximately equal to 1.22e1134 for f.
2. You're using a period ('.') to specify multiplication. In MuPAD, upon which most of the symbolic math functions are based, a period is shorthand for concatenation.
Additionally, as is stated in the R2015a documentation (and possibly earlier):
String inputs will be removed in a future release. Use syms to declare the variables instead, and pass them as a comma-separated list or vector.
If you had not used a string, I don't think that it would have been possible for your command to get misinterpreted and return such a confusing result. Here is how you could use solve with symbolic variables:
syms r;
n = sym(500);
A = sym(1000000);
d = n/A;
s = solve(1==(d*sym(pi)*r^2)^n/factorial(n)*exp(-d*sym(pi)*r^2),r)
which, after several minutes, returns a 1,000-by-1 vector of solutions, all of which are complex. As #BenVoigt suggests, you can try the 'Real' option for solve. However, in R2015a at least, the four solutions returned in terms of lambertw don't appear to actually be real.
A couple things to note:
MATLAB is not using the values of A, d, and f from your workspace.
f . exp is not doing at all what you wanted, which was multiplication. It's instead becoming an unknown function fexp
Passing additional options of 'Real', true to solve gets rid of most of these extraneous conditions.
You probably should avoid calling the version of solve which accepts a string, and use the Symbolic Toolbox instead (syms 'r')

Developing a Secant Method Program for root finding

So I have been trying to develop a secant method program that can be used for finding the root of
f(x) = tanh(x) - (x / 3)
However the answer output is nowhere close. Every solution I have found seems a more complex way to solve it.
x = 2;
prevx = x;
for i = 1:20
x = x - (tanh(x)-(x/3))*((x-(prevx))/((tanh(x)-(x/3))-(tanh(prevx))-((prevx/3))));
prevx = prevx + x;
x
end
The answer should be 2.987. I am getting a negative number though for some reason.
You suppose to add up terms so replace minus in this line:
x = x - (tanh(x)-(x/3))*((x-(prevx))/((tanh(x)-(x/3))-(tanh(prevx))-((prevx/3))));
To a plus:
x = x + (tanh(x)-(x/3))*((x-(prevx))/((tanh(x)-(x/3))-(tanh(prevx))-((prevx/3))));
To get a desired result of 2.987 for x. Also remove x before the end of the loop.
Here is an alternative way to do it (#madbitloman is right on spot as for the error in your code).
The secant method can be illustrated as follows (from Wikipedia):
Now if we translate this into MATLAB code, that would look like this:
x(k) = x(k-1) - (f(x(k-1)))*((x(k-1) - x(k-2))/(f(x(k-1)) - f(x(k-2))));
What is left to be done is provide the algorithm with 2 initial estimates and some tolerance value to tell it when to stop searching for a root, i.e. when 2 consecutive entries in x are very close to each other.
Let's choose 2 and 4. The closer the estimates to the real root, the faster the convergence.
To avoid using tanh(x)-(x/3) inside the for loop, which could get messy, let's define an anonymous function that takes x as an argument:
f = #(x) tanh(x)-(x/3);
So that would be the f in the line of code above.
Therefore, the whole code would look like the following, with a tolerance of say 0.001:
clear
clc
%// Initial values and tolerance
x(1) = 2;
x(2) = 4;
f = #(x) tanh(x)-(x/3);
tolerance = 0.001;
%// Let's try from 3 to 15.
for k=3:15
x(k) = x(k-1) - (f(x(k-1)))*((x(k-1) - x(k-2))/(f(x(k-1)) - f(x(k-2))));
if abs(x(k)-x(k-1)) < tolerance
break
end
end
After running the code, x looks like this:
x =
2.0000 4.0000 2.9420 2.9839 2.9847
so it took 5 iterations to reach the desired tolerance. Note that due to floating arithmetic you might want to use a smaller tolerance because Matlab stores numbers with much more digits than 4.
Finally you can get the negative root as well using appropriate initial estimates like -2 and -4:
x =
-2.0000 -4.0000 -2.9420 -2.9839 -2.9847
Hope that helps somehow!

Evaluate Matlab symbolic function

I have a problem with symbolic functions. I am creating function of my own whose first argument is a string. Then I am converting that string to symbolic function:
f = syms(func)
Lets say my string is sin(x). So now I want to calculate it using subs.
a = subs(f, 1)
The result is sin(1) instead of number.
For 0 it works and calculates correctly. What should I do to get the actual result, not only sin(1) or sin(2), etc.?
You can use also use eval() to evaluate the function that you get by subs() function
f=sin(x);
a=eval(subs(f,1));
disp(a);
a =
0.8415
syms x
f = sin(x) ;
then if you want to assign a value to x , e.g. pi/2 you can do the following:
subs(f,x,pi/2)
ans =
1
You can evaluate functions efficiently by using matlabFunction.
syms s t
x =[ 2 - 5*t - 2*s, 9*s + 12*t - 5, 7*s + 2*t - 1];
x=matlabFunction(x);
then you can type x in the command window and make sure that the following appears:
x
x =
#(s,t)[s.*-2.0-t.*5.0+2.0,s.*9.0+t.*1.2e1-5.0,s.*7.0+t.*2.0-1.0]
you can see that your function is now defined by s and t. You can call this function by writing x(1,2) where s=1 and t=1. It should generate a value for you.
Here are some things to consider: I don't know which is more accurate between this method and subs. The precision of different methods can vary. I don't know which would run faster if you were trying to generate enormous matrices. If you are not doing serious research or coding for speed then these things probably do not matter.