Issue with Matlab solve function?

2019-02-27 04:33发布

问题:

The following command

syms x real;
f = @(x) log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);

and

solve(fpp(x)>0,x,'Real',true)

return the result

solve([0.0 < (8.0*exp(-1.0/x^2))/x^4 - (2.0*exp(-1.0/x^2))/x^2 - (6.0*log(x^2)*exp(-1.0/x^2))/x^4 + (4.0*log(x^2)*exp(-1.0/x^2))/x^6], [x == RD_NINF..RD_INF])

which is not what I expect.

The first question: Is it possible to force Matlab's solve to return the set of all solutions?

(This is related to this question.) Moreover, when I try to solve the equation

solve(fpp(x)==0,x,'Real',true)

which returns

ans =
-1.5056100417680902125994180096313

I am not satisfied since all solutions are not returned (they are approximately -1.5056, 1.5056, -0.5663 and 0.5663 obtained from WolframAlpha).

I know that vpasolve with some initial guess can handle this. But, I have no idea how I can generally find initial guessed values to obtain all solutions, which is my second question.

Other solutions or suggestions for solving these problems are welcomed.

回答1:

As I indicated in my comment above, sym/solve is primarily meant to solve for analytic solutions of equations. When this fails, it tries to find a numeric solution. Some equations can have an infinite number of numeric solutions (e.g., periodic equations), and thus, as per the documentation: "The numeric solver does not try to find all numeric solutions for [the] equation. Instead, it returns only the first solution that it finds."

However, one can access the features of MuPAD from within Matlab. MuPAD's numeric::solve function has several additional capabilities. In particular is the 'AllRealRoots' option. In your case:

syms x real;
f = @(x)log(x^2)*exp(-1/(x^2));
fp(x) = diff(f(x),x);
fpp(x) = diff(fp(x),x);
s = feval(symengine,'numeric::solve',fpp(x)==0,x,'AllRealRoots')

which returns

s =

[ -1.5056102995536617698689500437312, -0.56633904710786569620564475006904, 0.56633904710786569620564475006904, 1.5056102995536617698689500437312]

as well as a warning message.

My answer to this question provides other way that various MuPAD solvers can be used, particularly if you can isolate and bracket your roots.

The above is not going to directly help with your inequalities other than telling you where the function changes sign. For those you could try:

s = feval(symengine,'solve',fpp(x)>0,x,'Real')

which returns

s =

(Dom::Interval(0, Inf) union Dom::Interval(-Inf, 0)) intersect solve(0 < 2*log(x^2) - 3*x^2*log(x^2) + 4*x^2 - x^4, x, Real)

Try plotting this function along with fpp.

While this is not a bug per se, The MathWorks still might be interested in this difference in behavior and poor performance of sym/solve (and the underlying symobj::solvefull) relative to MuPAD's solve. File a bug report if you like. For the life of me I don't understand why they can't better unify these parts of Matlab. The separation makes not sense from the perspective of a user.