symbolic cubic polynomial solver

Cubic polynomial always has a zero point on the real line, so I run something like
syms x a
solve(x^3+x^2-x+a,'real',true)
ans =
sin(atan((2*(1/27 - a^2/4)^(1/2))/a)/3) -...
1/(3*((a^2/4 - 1/27)^(1/2) - a/2)^(1/3)) + ...
sin(atan((2*(1/27 - a^2/4)^(1/2))/a)/3 - pi/3)...
- 1/(3*(a/2 - (a^2/4 - 1/27)^(1/2))^(1/3))...
- sin(atan((2*(1/27 - a^2/4)^(1/2))/a)/3)...
- sin(atan((2*(1/27 - a^2/4)^(1/2))/a)/3 - pi/3) -...
(2*3^(1/2)*cos(atan((2*(1/27 - a^2/4)...
(2*3^(1/2)*cos(atan((2*(1/27 - a^2/4)^(1/2))...
I cut the ... part b/c it's too long, but my point is that Matlab gave me 8 solutions. Can somebody tell me what is going on? Where is the fundamental theorem of algebra?

 採用された回答

John D'Errico
John D'Errico 2015 年 3 月 15 日

0 投票

Hmm. Did you tell it what to solve for? Should MATLAB magically know that x was your unknown, and a only a symbolic constant, for which you have chosen not to supply a value?
solve(x^3+x^2-x+a,x)
This returns 3 solutions. A problem is that 1 or 3 of them MAY be real, depending on the value of a. Since you won't tell MATLAB what is a, it can't know yet which one(s) are real.

6 件のコメント

Sakai
Sakai 2015 年 3 月 15 日
I included ",x" but still I get something wierd as follows. I guess " 'real',true " part is causing the problem... He is the exact code (I did not cut anything)
syms x a solve(x^3+x^2-x+a,x,'real',true) Warning: The solutions are valid under the following conditions: in(cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3), 'real') & a <= -11/27 & (a/2 + 11/54)^2 < 64/729; in(cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3), 'real') & -11/27 < a & (a/2 + 11/54)^2 < 64/729; a/2 + 11/54 <= ((a/2 + 11/54)^2 - 64/729)^(1/2) & in(4/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) + (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3), 'real') & 64/729 <= (a/2 + 11/54)^2; ((a/2 + 11/54)^2 - 64/729)^(1/2) < a/2 + 11/54 & 64/729 <= (a/2 + 11/54)^2 & in(- 4/(9*(a/2 - ((a/2 + 11/54)^2 - 64/729)^(1/2) + 11/54)^(1/3)) - (a/2 - ((a/2 + 11/54)^2 - 64/729)^(1/2) + 11/54)^(1/3), 'real'); in(- (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - (2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3, 'real') & a <= -11/27 & (a/2 + 11/54)^2 < 64/729; in((2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3, 'real') & a <= -11/27 & (a/2 + 11/54)^2 < 64/729; in(- (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - (2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3, 'real') & -11/27 < a & (a/2 + 11/54)^2 < 64/729; in((2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3, 'real') & -11/27 < a & (a/2 + 11/54)^2 < 64/729. To include parameters and conditions in the solution, specify the 'ReturnConditions' option. > In solve>warnIfParams at 518 In solve at 361
ans =
(4*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - 1/3
(4*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - 1/3
4/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) + (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3) - 1/3
- 4/(9*(a/2 - ((a/2 + 11/54)^2 - 64/729)^(1/2) + 11/54)^(1/3)) - (a/2 - ((a/2 + 11/54)^2 - 64/729)^(1/2) + 11/54)^(1/3) - 1/3
- (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - (2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - 1/3
(2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - 1/3
- (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - (2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - 1/3
(2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - 1/3
>>
John D'Errico
John D'Errico 2015 年 3 月 15 日
編集済み: John D'Errico 2015 年 3 月 15 日
Did you try what I showed? (Yes, it gives a warning, because it has no idea what is a. I've cut out the warning, because it is long.)
solve(x^3+x^2-x+a,x)
ans =
4/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) + (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3) - 1/3
- (3^(1/2)*(4/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) - (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3))*i)/2 - 2/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) - (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)/2 - 1/3
(3^(1/2)*(4/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) - (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3))*i)/2 - 2/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) - (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)/2 - 1/3
There are THREE solutions there, as you would expect. As I pointed out, even though you WANT to insist on the solution being real, how does MATLAB know which one is real? See that if I substitute some actual value for a, I can get various numbers of real solutions. Until a is known, there is no way to resolve the problem.
vpasolve(x^3+x^2-x+0,x)
ans =
-1.6180339887498948482045868343656
0
0.61803398874989484820458683436564
vpasolve(x^3+x^2-x+2,x)
ans =
-2.0
0.5 + 0.86602540378443864676372317075294*i
0.5 - 0.86602540378443864676372317075294*i
As I pointed out, depending on the value of a, there may be 3 solutions, OR 1 of them. And that one real solution, IF there is only one of them, will vary depending on a.
Trying to tell MATLAB that the solution must be real when it has no idea what a is, this is just a waste of time.
Sakai
Sakai 2015 年 3 月 15 日
I get the same answer as yours if I omit " 'real',true ". That's for sure. I also understand that if I do not tell Matlab anything about a, Matlab may not be able to choose.
What I still do not understand is, "then why does Matlab return 8 answers? Shouldn't the answers be at most 3?"
By the way, Matlab DOES choose the right answer even without any information on a, if I choose a shorter equation.
solve(x^3+a,x,'real',true)
ans =
-abs(a)^(1/3)*sign(a)
Actually, this expression is different from when you omit 'real',true
solve(x^3+a,x)
ans =
(-a)^(1/3)
(-a)^(1/3)*((3^(1/2)*i)/2 - 1/2)
-(-a)^(1/3)*((3^(1/2)*i)/2 + 1/2)
So it seems Matlab gives correct answer sometimes and gives wired answers other times... I am dying to know the latter case...
John D'Errico
John D'Errico 2015 年 3 月 15 日
編集済み: John D'Errico 2015 年 3 月 15 日
You are not listening to me.
MATLAB CANNOT know if a solution is real, IF you do not tell it the value of a. It has no idea how many solutions there will be to be found.
When I call it as you have done...
syms x a
xsols = solve(x^3+x^2-x+a,'real',true);
(LONG set of conditions deleted.)
numel(xsols)
ans =
8
There are indeed 8 solutions returned, BUT my guess is they are not independent solutions. Read the warning message:
"Warning: The solutions are valid under the following conditions: ..."
Depending upon the value of a, some of those conditions will be true or not. But MATLAB does not know which solution is real, since it does not know what is a.
So let us see what we get...
vpa(subs(xsols,a,-23),10)
ans =
2.650704467
1.158685567 - 2.31193163*i
2.650704467
- 1.825352233 - 2.31193163*i
- 1.825352233 + 2.31193163*i
- 1.825352233 - 2.31193163*i
1.158685567 + 2.31193163*i
-3.317371133
vpa(subs(xsols,a,0),10)
ans =
0.9513673221
0.6180339887
0.6180339887
-1.618033989
-1.284700655
-0.6666666667
8.67361738e-19
-1.618033989
vpa(subs(xsols,a,100),10)
ans =
4.410160108
2.038413387 + 3.942361499*i
2.038413387 - 3.942361499*i
-5.076826775
- 2.705080054 - 3.942361499*i
- 2.705080054 + 3.942361499*i
2.038413387 - 3.942361499*i
-5.076826775
As you can see, when I try different values of a, I get different real solutions. In fact, when a was zero, as you can see, many of those solutions reduce to the same solution.
Are they all truly roots though?
xsols_0 = vpa(subs(xsols,a,0))
xsols_0 =
0.95136732208322818153792016769897
0.61803398874989484820458683436564
0.61803398874989484820458683436564
-1.6180339887498948482045868343656
-1.2847006554165615148712535010323
-0.66666666666666666666666666666667
2.7550648847397363468017262591146e-40
-1.6180339887498948482045868343656
subs(x^3 + x^2 - x + 0,x,xsols_0)
ans =
0.81481481481481481481481481481481
-2.7550648847397363468017262591146e-40
2.2958874039497802890014385492622e-40
0
0.81481481481481481481481481481481
0.81481481481481481481481481481481
-2.7550648847397363468017262591146e-40
0
So when I substituted those values back into the equation, in fact not all solutions were roots! This is true because the corresponding condition that MATLAB gave you were in fact false when a was zero.
So, yes, it gave you 8 solutions, DEPENDING on the value of a. It was not wired. Simply, as I have said many times now, it does not know what is a.
Sakai
Sakai 2015 年 3 月 15 日
Now I understand what you really mean. Thank you very much!
John D'Errico
John D'Errico 2015 年 3 月 15 日
Good. I do admit that until I decided to do those last few things, I think there was some confusion as to why MATLAB was returning 8 solutions, or what appeared to be 8 of them.

サインインしてコメントする。

その他の回答 (1 件)

Andrew Newell
Andrew Newell 2015 年 3 月 15 日
編集済み: Andrew Newell 2015 年 3 月 15 日

0 投票

I ran the same code and got 3 solutions:
syms x a
xsols = solve(x^3+x^2-x+a,'real',true);
size(xsols)
ans =
3 1
I think you're interpreting those eight lines as one solution per line, but the triple dots at the end of the line mean that the solution continues on the next line. You are really just displaying one of the three solutions.

4 件のコメント

Sakai
Sakai 2015 年 3 月 15 日
I tried
syms x a
sol=solve(x^3+x^2-x+a,x,'real',true)
and see the dimension of "sol" is 8 times 1 on the workspace pane. So I suspect perhaps Matlab is really returning 8 different answers...
Sakai
Sakai 2015 年 3 月 15 日
Strange... I copy your code and paste it in my Matlab (2014b) as it is, and the following is what I got... version problem...?
>> syms x a
xsols = solve(x^3+x^2-x+a,'real',true);
size(xsols)
Warning: The solutions are valid under the following conditions: in(cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3), 'real') & a <= -11/27 & (a/2 + 11/54)^2 < 64/729; in(cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3), 'real') & -11/27 < a & (a/2 + 11/54)^2 < 64/729; a/2 + 11/54 <= ((a/2 + 11/54)^2 - 64/729)^(1/2) & in(4/(9*(((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3)) + (((a/2 + 11/54)^2 - 64/729)^(1/2) - a/2 - 11/54)^(1/3), 'real') & 64/729 <= (a/2 + 11/54)^2; ((a/2 + 11/54)^2 - 64/729)^(1/2) < a/2 + 11/54 & 64/729 <= (a/2 + 11/54)^2 & in(- 4/(9*(a/2 - ((a/2 + 11/54)^2 - 64/729)^(1/2) + 11/54)^(1/3)) - (a/2 - ((a/2 + 11/54)^2 - 64/729)^(1/2) + 11/54)^(1/3), 'real'); in(- (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - (2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3, 'real') & a <= -11/27 & (a/2 + 11/54)^2 < 64/729; in((2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3 - (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3))/3, 'real') & a <= -11/27 & (a/2 + 11/54)^2 < 64/729; in(- (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - (2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3, 'real') & -11/27 < a & (a/2 + 11/54)^2 < 64/729; in((2*3^(1/2)*sin(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3 - (2*cos(atan((64/729 - (a/2 + 11/54)^2)^(1/2)/(a/2 + 11/54))/3 - pi/3))/3, 'real') & -11/27 < a & (a/2 + 11/54)^2 < 64/729. To include parameters and conditions in the solution, specify the 'ReturnConditions' option. > In solve>warnIfParams at 518 In solve at 361
ans =
8 1
Andrew Newell
Andrew Newell 2015 年 3 月 15 日
It appears that in 2014a, the option 'real',true didn't have any effect; but in 2014b, the engine is trying to figure out what parts of the solution are real.
Consider: in complex space, for each value of a (which, as far as solve knows might be complex) you have three complex solutions. Without 'real',true, solve is returning the equations for (real(x), imag(x)) as a function of (real(a), imag(a)) - not a line, but a surface. With 'real',true, it is trying to determine where this surface intersects imag(x) = 0. That could be any number of line segments.
Sakai
Sakai 2015 年 3 月 15 日
I see. Thank you very much!

サインインしてコメントする。

製品

質問済み:

2015 年 3 月 15 日

コメント済み:

2015 年 3 月 15 日

Community Treasure Hunt

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

Start Hunting!

Translated by