Pi, Matlab Symbolic math toolbox have a bug? - matlab

Hello i have one question. When I calculate a division in matlab: x/(pi.^2)
syms x
x/(pi.^2)
ans =
(281474976710656*v)/2778046668940015
the correct answer is x/9.8696, so why is matlab giving me this result?
Is it a bug?

You have to use the vpa() command "Variable-precision arithmetic". Check this code:
syms x real; % define x as a real symbolic variable (not a complex variable)
vpa( x/(pi.^2), 5) % second argument define number of significant digits
For trigonometric expressions involving pi, it is sometimes good to define sym('pi'):
syms x real;
pi_s = sym('pi');
expr = x/pi_s^2
I try to always use the 'real' tag when using the symbolic toolbox. If you do not use it you are going to see a lot of complex conjugates and other things that are not important for your problem, because x is probably real variable.
Hope this helps,

No it is not a bug:
2778046668940015/281474976710656 = 9.8696

Related

compute derivative of first order function

I have a problem when computing the derivative of a first order function as below:
syms x(t)
xd = diff(x);
y = xd*xd;
how to compute derivative of y by xd;
functionalDerivative(y,xd);
Then, it raises an error as below:
Error using symengine
The variable 'diff(x(t), t)' is invalid.
The result should be:
2*diff(x,t)
I also think about name xd as a symbolic variable, then use diff(y,xd) but this way is not good for some situation. Do we have any method can directly compute the derivative of a differential function?
Please suggest me some solutions.
Thank in advance!
I find it a little odd that the Symbolic Engine can't handle that, lacking a better word I'll borrow one from the TeX world, unexpandable expression. However, you can get around the limitation by subs-ing in a temporary variable, taking the derivative, and subs-ing it back in:
>> syms u(t)
>> dydxd = subs(functionalDerivative(subs(y,xd(t),u(t)),u),u(t),xd(t))
dydxd(t) =
2*diff(x(t), t)
Hopefully this subs approach will work in most cases, but more complex expressions for y may make it not work.

Solve a polynomial equation of degree 4

I got this equation after I solved that problem here
I would like to solve it using Matlab.
The function roots returns polynomial roots. Simply pass the coefficients:
roots([1,-6,-36,216,-324])
Use solve from MATLAB's symbolic mathematics toolbox:
>> syms x;
>> y = solve('x^4-6*x^3-36*x^2+216*x-324==0')
y =
7.7446378738164683022795580182987
-6.3360292312480789716536487435108
2.2956956787158053346870453626061 - 1.1543655214730370697054534567177*i
2.2956956787158053346870453626061 + 1.1543655214730370697054534567177*i
The first line of code declares that x is a symbolic mathematics variable that we can use with the toolbox. Next, we use solve and we put in a string that describes the equation that is seen in your post. Bear in mind that when we multiply coefficients, you need to use the * operator, and for equality, we need to use double equals, or ==. The output should give you four roots, as dictated by the fundamental theorem of algebra. You'll see that you have two real roots, as well as two imaginary roots.
Alternatively, you can use roots in MATLAB by specifying a vector of coefficients starting from the highest order down to the lowest as per Daniel's answer.

How to solve an equation with piecewise defined function in Matlab?

I have been working on solving some equation in a more complicated context. However, I want to illustrate my question through the following simple example.
Consider the following two functions:
function y=f1(x)
y=1-x;
end
function y=f2(x)
if x<0
y=0;
else
y=x;
end
end
I want to solve the following equation: f1(x)=f2(x). The code I used is:
syms x;
x=solve(f1(x)-f2(x));
And I got the following error:
??? Error using ==> sym.sym>notimplemented at 2621
Function 'lt' is not implemented for MuPAD symbolic objects.
Error in ==> sym.sym>sym.lt at 812
notimplemented('lt');
Error in ==> f2 at 3
if x<0
I know the error is because x is a symbolic variable and therefore I could not compare x with 0 in the piecewise function f2(x).
Is there a way to fix this and solve the equation?
First, make sure symbolic math is even the appropriate solution method for your problem. In many cases it isn't. Look at fzero and fsolve amongst many others. A symbolic method is only needed if, for example, you want a formula or if you need to ensure precision.
In such an old version of Matlab, you may want to break up your piecewise function into separate continuous functions and solve them separately:
syms x;
s1 = solve(1-x^2,x) % For x >= 0
s2 = solve(1-x,x) % For x < 0
Then you can either manually examine or numerically compare the outputs to determine if any or all of the solutions are valid for the chosen regime – something like this:
s = [s1(double(s1) >= 0);s2(double(s2) < 0)]
You can also take advantage of the heaviside function, which is available in much older versions.
syms x;
f1 = 1-x;
f2 = x*heaviside(x);
s = solve(f1-f2,x)
Yes, the Heaviside function is 0.5 at zero – this gives it the appropriate mathematical properties. You can shift it to compare values other than zero. This is a standard technique.
In Matlab R2012a+, you can take advantage of assumptions in addition to the normal relational operators. To add to #AlexB's comment, you should convert the output of any logical comparison to symbolic before using isAlways:
isAlways(sym(x<0))
In your case, x is obviously not "always" on one side or the other of zero, but you may still find this useful in other cases.
If you want to get deep into Matlab's symbolic math, you can create piecewise functions using MuPAD, which are accessible from Matlab – e.g., see my example here.

Using unspecified constants in matlab

I'm trying to solve a system of equations in the s-domain. So set up this system of equations in matrix form:
a=[.4*s+s+5 -5; -5 .5*s+5]
c=[3/s; 3/(2*s)]
(1/s)*a*b=c
I just get the error that s is undefined.
How can I solve for b in terms of s?
Matlab does not (naturally) do symbolic calculations --- which is what your code is trying to do. Matlab's variables need to be concrete numbers, or arrays, or structures, etc. They cannot just be placeholders for arbitrary numbers.
(UNLESS: You use the symbolic computing toolbox for Matlab. I haven't really used this because I prefer to do symbolic computing in environments such as Maple or Mathematica. You could even solve your problem on the Wolfram Alpha website)
But if you pick a specific value of s, computing what you want is easy:
s = 5;
a=[.4*s+s+5 -5; -5 .5*s+5];
c=[3/s; 3/(2*s)];
b = s*(a\c);
Where I have used the backslash operator for doing linear inversion.
You should now have that
(1/s)*a*b-c
is the zero vector.
EDIT: I looked into the symbolic toolbox. It looks like this is what you want (but you need to have the symbolic toolbox licensed and installed for it to work):
syms s;
a=[.4*s+s+5 -5; -5 .5*s+5];
c=[3/s; 3/(2*s)];
b = simple(s*(a\c))
The code to perform your calculation using symbolic operators is:
syms s; %This defines 's' as a symbolic token
a=[.4*s+s+5 -5; -5 .5*s+5]; %a and c inherit the symbolic properties from s
c=[3/s; 3/(2*s)];
result = solve('(1/s)*a*b=c','b') %Solve is the general symbolic toolbox algebraic solver.
This produces
result =
(c*s)/a
Generally speaking, Matlab performs best as a numerical toolbox. So depending on your application I would go with another approach, such as that demonstrated by Ian Hincks in another answer. But sometimes the situation demands a symbolic solution.

MATLAB | calculating parameters of gamma dist based on mean and probability interval

I have a system of 2 equations in 2 unknowns that I want to solve using MATLAB but don't know exactly how to program. I've been given some information about a gamma distribution (mean of 1.86, 90% interval between 1.61 and 2.11) and ultimately want to get the mean and variance. I know that I could use the normal approximation but I'd rather solve for A and B, the shape and scale parameters of the gamma distribution, and find the mean and variance that way. In pseudo-MATLAB code I would want to solve this:
gamcdf(2.11, A, B) - gamcdf(1.61, A, B) = 0.90;
A*B = 1.86;
How would you go about solving this? I have the symbolic math toolbox if that helps.
The mean is A*B. So can you solve for perhaps A in terms of the mean(mu) and B?
A = mu/B
Of course, this does no good unless you knew B. Or does it?
Look at your first expression. Can you substitute?
gamcdf(2.11, mu/B, B) - gamcdf(1.61, mu/B, B) = 0.90
Does this get you any closer? Perhaps. There will be no useful symbolic solution available, except in terms of the incomplete gamma function itself. How do you solve a single equation numerically in one unknown in matlab? Use fzero.
Of course, fzero looks for a zero value. But by subtracting 0.90, that is resolved.
Can we define a function that fzero can use? Use a function handle.
>> mu = 1.86;
>> gamfun = #(B) gamcdf(2.11, mu/B, B) - gamcdf(1.61, mu/B, B) - 0.90;
So try it. Before we do that, I always recommend plotting things.
>> ezplot(gamfun)
Hmm. That plot suggests that it might be difficult to find a zero of your function. If you do try it, you will find that good starting values for fzero are necessary here.
Sorry about my first try. Better starting values for fzero, plus some more plotting does give a gamma distribution that yields the desired shape.
>> B = fzero(gamfun,[.0000001,.1])
B =
0.0124760672290871
>> A = mu/B
A =
149.085442218805
>> ezplot(#(x) gampdf(x,A,B))
In fact this is a very "normal", i.e, Gaussian, looking curve.