Message Boards Message Boards

Force Solve[ ] to obtain real expressions?

Posted 3 years ago

Hi,

I am trying to use Solve[] to obtain analytical roots of a third order polynomial of variable x:

F[x_,k_,kf_,kb_]:=(2*k/3)*x^3-(kf-kb*x)^2;

where k>0, kb>0, kf>0. By calling

Solve[F[x,k,kf,kb]==0,x]

I obtain some expressions involving imaginary unit. However, in many cases the roots should be real. This happens, for example, if

u=2;
k=10;
kf=Exp[-u/2];
kb=Exp[u/2];

(there are three distinct real roots in this case). I need real formulae applicable in such cases. How can I obtain them? I am trying various tricks but nothing works.

Leslaw

POSTED BY: Leslaw Bieniasz
14 Replies
Posted 3 years ago

Have you tried

Solve[F[x, k, kf, kb] == 0, x, Reals]
POSTED BY: Rohit Namjoshi

The command:

InputForm[Solve[F[x, k, kf, kb] == 0, x, Reals]]

produces the result:

{{x -> ConditionalExpression[Root[-3*kf^2 + 6*kb*kf*#1 - 3*kb^2*#1^2 + 2*k*#1^3 & , 1], (k > (2*kb^3)/(9*kf) && kb > 0 && kf > 0) || 
     (Inequality[0, Less, k, Less, (2*kb^3)/(9*kf)] && kb > 0 && kf > 0) || (Inequality[0, Less, k, Less, (2*kb^3)/(9*kf)] && kb < 0 && kf < 0) || 
     (Inequality[(2*kb^3)/(9*kf), Less, k, Less, 0] && kb < 0 && kf > 0) || (Inequality[(2*kb^3)/(9*kf), Less, k, Less, 0] && kf < 0 && kb > 0) || 
     (k < 0 && kb > 0 && kf > 0) || (k < 0 && kb < 0 && kf < 0) || (k < (2*kb^3)/(9*kf) && kb < 0 && kf > 0) || (k < (2*kb^3)/(9*kf) && kf < 0 && kb > 0) || 
     (kb < 0 && k > 0 && kf > 0) || (kb < 0 && kf < 0 && k > (2*kb^3)/(9*kf)) || (kf < 0 && k > 0 && kb > 0)]}, 
 {x -> ConditionalExpression[Root[-3*kf^2 + 6*kb*kf*#1 - 3*kb^2*#1^2 + 2*k*#1^3 & , 2], (Inequality[0, Less, k, Less, (2*kb^3)/(9*kf)] && kb > 0 && kf > 0) || 
     (Inequality[0, Less, k, Less, (2*kb^3)/(9*kf)] && kb < 0 && kf < 0) || (Inequality[(2*kb^3)/(9*kf), Less, k, Less, 0] && kb < 0 && kf > 0) || 
     (Inequality[(2*kb^3)/(9*kf), Less, k, Less, 0] && kf < 0 && kb > 0)]}, 
 {x -> ConditionalExpression[Root[-3*kf^2 + 6*kb*kf*#1 - 3*kb^2*#1^2 + 2*k*#1^3 & , 3], (Inequality[0, Less, k, Less, (2*kb^3)/(9*kf)] && kb > 0 && kf > 0) || 
     (Inequality[0, Less, k, Less, (2*kb^3)/(9*kf)] && kb < 0 && kf < 0) || (Inequality[(2*kb^3)/(9*kf), Less, k, Less, 0] && kb < 0 && kf > 0) || 
     (Inequality[(2*kb^3)/(9*kf), Less, k, Less, 0] && kf < 0 && kb > 0)]}}

I am afraid I don't see how this might be useful. Where are the analytical formulae? A third order polynomial should have analytical formulae for its roots. I also think that at least one root should always be real (if I remember the mathematics).

Leslaw

POSTED BY: Leslaw Bieniasz
Posted 3 years ago

You could try this:

F[x_, k_, kf_, kb_] := (2*k/3)*x^3 - (kf - kb*x)^2
Solve[{F[x, k, kf, kb] == 0, k > 0, kf > 0, kb > 0}, x, Reals] // ToRadicals

It gives one real and two complex roots

POSTED BY: Hans Milton

Hi, thanks, I tried this, but the result still raises questions. Firstly, the result contains conditional expressions which involve conditions such as kf>0, kb<0, etc. Why these conditions are still present, given the fact that it was assumed in the Solve command that k>0, kf>0 and kb>0 ? It looks as if these assumptions were ignored.

Secondly, how do you know that one root is real and the other two complex? All three formulae involve a square root which may produce the imaginary unit if the expression under the root is negative. There is evidence that often there are three real roots, which is easy to check by plotting the polynomial for k=10,kf=Exp[-1],kb=Exp[1]. Isn't there any way to transform/simplify the results returned by Solve to obtain evidently real-valued formulae for these real roots, together with the conditions specifying when they happen to be real?

Ultimately, what I need is a formula for the (supposedly single, but how to prove this?) real root satisfying an additional condition kf-kb*x >0. If I include this condition in the above command:

Solve[{F[x, k, kf, kb] == 0, k > 0, kf > 0, kb > 0, kf-kb*x>0}, x, Reals] // ToRadicals

I obtain indeed one formula for the root x. However, at least for k=10, kf=Exp[-1], kb=Exp[1] it is a wrong formula, because for such returned x there is kf-kb*x < 0.

Leslaw

POSTED BY: Leslaw Bieniasz

The documentation on ToRadicals states that "If Root objects in expr contain parameters, ToRadicals[expr] may yield a result that is not equal to expr for all values of the parameters."

POSTED BY: Gianluca Gorni
Posted 3 years ago

Leslaw, all three solutions are depending on conditional expressions. And they are, as you remarked, mostly "parrot like" repetitions of the input conditions. But the last two of the three has an imaginary unit in the nonconditional part. So no way those two solutions could convert to a real expression.

F[x_, k_, kf_, kb_] := (2*k/3)*x^3 - (kf - kb*x)^2
sols = Solve[{F[x, k, kf, kb] == 0, k > 0, kf > 0, kb > 0}, x, Reals] // ToRadicals;
Column@sols

But there is a new condition imposed to the first solution:

k > (2 kb^3)/(9 kf) && kb > 0 && kf > 0 || 0 < k < (2 kb^3)/(9 kf) && kb > 0 && kf > 0

Give it a try:

x /. First[sols] /. {k -> 4, kb -> 3, kf -> 2}
POSTED BY: Hans Milton

I disagree; the roots might sometimes be complex, but sometimes all of them are real. Please try:

u=2;
k=10;
kf=Exp[-u/2];
kb=Exp[u/2];
Plot[F[x,k,kf,kb],{x,-0.1,1}]

Clearly there are three real and positive roots in this case. The one located between the other two obeys the condition kf - kb*x > 0.

Leslaw

POSTED BY: Leslaw Bieniasz
Posted 3 years ago

Yes, you are right. And I was wrong. Since the solutions involves cube roots the explicit imaginary unit (in the last two) can of course sometimes be cancelled.

k=10, kf=Exp[-1] and kb=Exp[1] satisfies the condition:

0 < k < (2 kb^3)/(9 kf) && kb > 0 && kf > 0

And that condition occurs in all three solutions given by Solve

POSTED BY: Hans Milton

I guess you mean square roots, not cube roots? In the same way one can expect that the first formula (not involving the imaginary unit) may become complex, if the argument of the square root is negative. In effect one cannot predict a priori which of the formulae represents real and which complex roots. It seems I have to do all calculations by hand, from the scratch, using some math book, as I cannot rely on MATHEMATICA to do the job and find the real root satisfying kf - kb*x > 0. This is disappointing.

Leslaw

POSTED BY: Leslaw Bieniasz

We can ask Reduce to find conditions so that a Root object coincides with an expression with radicals:

F[x_, k_, kf_, kb_] := (2*k/3)*x^3 - (kf - kb*x)^2;
{rad1, rad2, rad3} = 
  x /. Solve[F[x, k, kf, kb] == 0, x] // ToRadicals // Simplify;
Reduce[F[x, k, kf, kb] == 0
  && k > 0 && kf > 0 && kb > 0 && kf - kb*x > 0, x, Reals]
Reduce[rad1 == 
   Root[-3 kf^2 + 6 kb kf #1 - 3 kb^2 #1^2 + 2 k #1^3 &, 1] &&
  k > 0 && kf > 0 && kb > 0, {k, kf, kb}, Reals]

Unfortunately, it does not seem to work for rad2 and rad3.

POSTED BY: Gianluca Gorni
Posted 3 years ago

This seems to work when the condition kf-kb*x>0 is added:

F[x_, k_, kf_, kb_] := (2*k/3)*x^3 - (kf - kb*x)^2

genSol = x /. Solve[{F[x, k, kf, kb] == 0, k > 0, kf > 0, kb > 0, kf - kb*x > 0}, x, Reals] // ToRadicals // First

specSol = genSol /. {k -> 10, kf -> Exp[-1], kb -> Exp[1]} // ComplexExpand // Simplify

specSol // N
(* 0.740044 *)
POSTED BY: Hans Milton

But the root 0.740044... does not, in fact, satisfy the condition kf - kb*x > 0. It has a too big value. I think the condition is satisfied only by the smallest of the three real positive roots that occur for these data (I previously stated erroneously that it was the middle root).

Leslaw

POSTED BY: Leslaw Bieniasz
Posted 3 years ago

Deleted. Sorry Leslaw, I made another mistake. Posting too hastily.

POSTED BY: Hans Milton
Posted 3 years ago

Taking another approach, using Select to pick the root(s) which satisfies kf - kb * x > 0

The functions:

F[x_, k_, kf_, kb_] := (2*k/3)*x^3 - (kf - kb*x)^2
allRoots[k_, kf_, kb_] := 
 x /. Solve[F[x, a, b, c] == 0, x, Reals] /. {a -> k, b -> kf, c -> kb} // ToRadicals // ComplexExpand // Simplify
specRoot[k_, kf_, kb_] := Select[allRoots[k, kf, kb], kf - kb*# > 0 &]

Trying it out on some cases:

rootA = specRoot[10, Exp[-1], Exp[1]]
rootA // N
(* {0.103642} *)

rootB = specRoot[1, 2, 3]
rootB // N
(* {0.554337} *)

rootC = specRoot[1, 3, 2]
rootC // N
(* {1.0566} *)

The last case has a single real root.

POSTED BY: Hans Milton
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract