Why does the following expression result in error? - matlab

Disclaimer. I am familiar with Mathematica but not Matlab, so I apologize if this is a neophyte question.
I am getting a strange error on Matlab on the the following at using Matlab's solve command:
solve(0.2 = (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))), M)
The error is:
Error: The expression to the left of the equals sign is not a valid target for an assignment.
The equivalent Solve command in Mathematica (using the same expression) works perfectly, so I don't think my expression itself is invalid.
Moreover, I get the same error when I try to use the examples on the doc site: http://www.mathworks.com/help/symbolic/mupad_ref/solve.html
Is it a configuration problem or is there something about the syntax of the command I am misinterpreting?
Edit: I also tried with == instead of =, and I get a different error:
Undefined function or variable 'M'.
Also, as a note, I am running Matlab R2011b (7.13.0.564) 64-bit (glnxa64).
Edit2: I tried the first suggested solution with syms:
>> syms M
>> solve(0.2 == (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))), M)
Error using char
Conversion to char from logical is not possible.
Error in solve>getEqns (line 245)
vc = char(v);
Error in solve (line 141)
[eqns,vars,options] = getEqns(varargin{:});
Edit3: I have been able to reproduce this issue with even the simplest of equations
>> syms x
>> solve(x^2 -4 == 0, x)
Error using char
Conversion to char from logical is not possible.
Error in solve>getEqns (line 245)
vc = char(v);
Error in solve (line 141)
[eqns,vars,options] = getEqns(varargin{:});
Moreover, I tried the solution suggested here too: MATLAB examples are failing

Matlab's fsolve command assumes the expression is set to zero. If solving numerically, you would not do:
x=solve(2=x+1,x)
but rather:
x=fsolve(#(x) x+1-2,0)
Where the equation is already set to zero, #(x) is what you are solving for, and 0 is the initial guess. Which you must include.
Using solve symbolically, it looks like this:
syms x
val=solve(x+1-2)
Or for your system:
syms M
solve(-0.2+ (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))))
ans =
4.7161724968093348297842999805458
0.029173662296926424763929809009225
- 3.8716404782846254923900841980317 - 3.4984412176176158766571497649425*i
1.4989673987314948651159693032542 + 5.5784387926679222829321168661041*i
1.4989673987314948651159693032542 - 5.5784387926679222829321168661041*i
- 3.8716404782846254923900841980317 + 3.4984412176176158766571497649425*i

you should define M as sym, and use == instead of =
syms M
solve(0.2 == (1.4+1/2)^((1.4+1)/(2*(1.4-1)))*(M)/((1+(1.4-1)/2*M^2))^((1.4+1)/(2*(1.4-1))), M)
ans =
4.7161724968093348297842999805458
0.029173662296926424763929809009225
- 3.8716404782846254923900841980317 - 3.4984412176176158766571497649425*i
1.4989673987314948651159693032542 + 5.5784387926679222829321168661041*i
1.4989673987314948651159693032542 - 5.5784387926679222829321168661041*i
- 3.8716404782846254923900841980317 + 3.4984412176176158766571497649425*i

Related

"Unable to prove literally" error when trying to create a symbolic function based on an existing function

I need to find inverse of virtual value function of lognormal random variables. This is what I tried to do:
syms flogn(x,p1,p2)
% assume(p2<=0); %Adding this doesn't change the error
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
glogn = finverse(flogn,x);
But I got the error:
Error using symengine
Unable to prove 'p2 <= 0' literally. Use 'isAlways' to test the statement mathematically.
Error in sym/subsindex (line 810)
X = find(mupadmex('symobj::logical',A.s,9)) - 1;
Error in sym/privsubsasgn (line 1085)
L_tilde2 = builtin('subsasgn',L_tilde,struct('type','()','subs',{varargin}),R_tilde);
Error in sym/subsasgn (line 922)
C = privsubsasgn(L,R,inds{:});
Error in logncdf>locallogncdf (line 73)
sigma(sigma <= 0) = NaN;
Error in logncdf (line 47)
[varargout{1:max(1,nargout)}] = locallogncdf(uflag,x,varargin{:});
Error in Untitled5 (line 3)
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
I also tried with beta distribution, and got a similar error. How can I use logncdf with symbolic variables?
Note that you could have minimalize your sample code even more, like this:
syms flogn(x,p1,p2)
flogn(x,p1,p2) = logncdf(x,p1,p2);
It's shorter, produces the same error and helps us to focus on the source of the error message.
So, the error doesn't come from trying to inverse a function, but from trying to use an existing function for numerical calculations with symbolic variables.
The error comes from the fact that you want to create a symbolic function flogn based on existing function logncdf, and logncdf has a multiple comparisons.
With the command edit logncdf, you can read the source code of the function and see comparison at lines 73 and 76.
% Return NaN for out of range parameters.
sigma(sigma <= 0) = NaN;
% Negative data would create complex values, which erfc cannot handle.
x(x < 0) = 0;
Matlab cannot compare symbols so it throws errors.
Depending on what you really need, you can have different solutions.
Do you really need to symbolize the function flogn? Couldn't you just write it as a function then calculate the inverse of it (if it can be inversed...)?
If you really want to keep the symbolization, you can also rewrite your own function logncdf (with another name) so it does not have the comparisons. But it's still not guaranteed that you will find an inverse.

Getting conversion error while using solve function on an expression generated using for loop in MATLAB?

I am trying to find the first term 'p' of a geometric series with common ratio 1.05 in MATLAB as follows. However the solve function is giving the error as below (posted right after the code). I can't seem to figure out the reason for this error, because when I display the expression for 'sum', it is correctly showing an expression in terms of'p', but the problem arises when I try to equate that to a value, and solve for 'p'. Any insights would be appreciated! Thanks.
clear all;
clc;
t=20; %no. of terms in geometric series
sum =0;
jackpot = 1000; %sum of geometric series
%p is first term
syms p
for x=1:t
sum = sum + p*((1.05)^(x-1));
end
disp(sum);
eqn1 = sum == jackpot;
solve(eqn1,p);
Output:
(18614477322052275759*p)/562949953421312000
??? Error using ==> char
Conversion to char from logical is not possible.
Error in ==> solve>getEqns at 169
vc = char(v);
Error in ==> solve at 67
[eqns,vars] = getEqns(varargin{:});
Error in ==> geometric_trial at 13
solve(eqn1,p);
So, I got the answer for this from a user Walter Roberson on another forum. Posting here, from his answer.
I was trying this on a version of MATLAB which is really old i.e. R2010a. In this, using 'symbolic_expression == symbolic_expression' does not set up an equation for later solving, but instead compares the two expressions for literal equality and returns a logical value immediately.
In versions that old, the easiest fix is to change
eqn1 = sum == jackpot
to
eqn1 = (sum) - (jackpot)
and let solve() deal with the implicit equality to 0.

Solve function not working

I'm currently trying to solve an equation with the solve function but I keep getting errors.
This is my code:
Dh=0.02;
Lc1=1.6;
Prw=9;
a=0.03*(Dh/Lc1)*Prw;
b=0.016*(Dh/Lc1)^(2/3)*Prw^(2/3);
c=9;
d=7.54;
syms Redh
eqn = (c*b-d*b)*Redh^(2/3)-a*Redh == d-c;
solRedh = solve(eqn,Redh);
When i run this i get the error
Warning: The solutions are
parameterized by the symbols: z2.
To include parameters and conditions
in the solution, specify the
'ReturnConditions' option.
In solve>warnIfParams (line 500)
In solve (line 356)
In Massflow_1 (line 105)
Warning: The solutions are valid under
the following conditions: 3*z2^2 + z2^3
- 59/50 == 0 & -pi/3 < angle(z2) &
angle(z2) <= pi/3.
To include parameters and conditions
in the solution, specify the
'ReturnConditions' option.
In solve>warnIfParams (line 507)
In solve (line 356)
In Massflow_1 (line 105)
I don't understand why the answer is parameterized by the symbol z2. There should be a solution containing a value. Even if i simplify it to an equation with the same powers of which I'm certain there is an answer to I get the same error.
Simpeler code
syms Redh
eqn = 0.0054*Redh^(2/3)-0.0034*Redh == -1.46;
solRedh = solve(eqn,Redh);
Does anybody know what is going wrong here and how I can fix it? It would be very helpful, thank you!
In your case, matlab use the symbol 'z2' to show that the solution use a complex number.(z2 ∈ Z)
You need to explain to matlab that you are not interested by a complex solution.
It should work without problem with:
% set an assumptions on symbolic variables! here our solution need to be a real number.
syms Redh real %check the doc for more informations about the assumptions.
eqn = 0.0054*Redh^(2/3)-0.0034*Redh == -1.46;
sol_sym = solve(eqn,Redh);
sol_nosym = double(sol_sym);

Error using mupadmex, Error in sym/symsum (Evaluate a definite integral)

I am trying to evaluate a definite integral using the following code :
m=4;
t=4;
n=5;
P=10;
reset(symengine)
syms x;
syms k;
mean=int(log(1+P*x/t)*symsum( factorial(k)*x^(n-m)*exp(-x)/factorial(k+n-m)*feval(symengine,'laguerreL',n-m,k,x)*feval(symengine,'laguerreL',n-m,k,x),k,[0,m-1]) ,x,0,inf)
But it gives the following error:
Error using mupadmex
Error in MuPAD command: The number of arguments is incorrect. [has]
Evaluating: sum
Error in sym/symsum (line 114)
rSym = mupadmex('symobj::map',fsym.s,'symobj::symsum',x.s,a.s,b.s);
Error in Untitled2 (line 32)
mean=int(log(1+P*x/t)*symsum( factorial(k)*x^(n-m)*exp(-x)/factorial(k+n-m)*feval(symengine,'laguerreL',n-m,k,x)*feval(symengine,'laguerreL',n-m,k,x),k,[0,m-1]) ,x,0,inf)
However, when I evaluate the integral without some functions:
mean=int(log(1+P*x/t)*symsum( feval(symengine,'laguerreL',n-m,k,x)*feval(symengine,'laguerreL',n-m,k,x),k,[0,m-1]) ,x,0,inf)
I get an answer which is Inf. Any idea?
I found the solution. it consists in using gamma(k+n-m+1) to compute (k+n-m)!, since there is a bug when performing the factorial of a symbolic variables.

"Unable to prove `expr` literally..." error when trying to compare a symbol inside a function

I just started learning MATLAB and I'm trying to normalize a bump function given by
function b = bump(x)
region1 = abs(x) < 1
b(region1) = (exp(-1./(1 - x(region1).^2)))
region2 = abs(x) >= 1
b(region2) = 0
end
To do this, I need to divide by the definite integral from -1 to 1. However, when I input
syms x;
int(bump(x), -1, 1)
I get a long error message, which says
Error using symengine (line 58)
Unable to prove 'abs(x) < 1' literally. To test the statement mathematically, use isAlways.
Error in sym/subsindex (line 1554)
X = find(mupadmex('symobj::logical',A.s,9)) - 1;
Error in sym>privformat (line 2357)
x = subsindex(x)+1;
Error in sym/subsref (line 1578)
[inds{k},refs{k}] = privformat(inds{k});
Error in bump (line 3)
b(region1) = (exp(-1./(1 - x(region1).^2)))
I tried replacing abs(x)<1 with what I think is the suggested isAlways(abs(x)<1), and that removes the error, although it gives the wrong answer (it says the integral is zero).
I don't understand what does the error message means.
syms x defines x as a symbolic variable, invoking symbolic computation on x. This probably isn't what you want.
Instead, define x as some kind of input matrix, e.g. x = zeros(3);. Or, to do numeric integration, use the integral function:
integral(#bump, -1, 1)