Solve exp(x) = a with real solution only



Piet van Oostrum <piet at vanoostrum.org> writes:
> I want to solve equations of the form exp(x/c) = v and obtain only a
> real solution. I use this to solve equations in RC electronic
> networks. Sometimes the equation is a bit more complicated with a factor
> and a constant added to it, so I cannot just apply log to it. The
> problem is that solve generates complex solutions and if c is large this
> can become vey unwieldy.
>
> (%i1) EQ: exp(x*5) = 0.5 ;
>
> (%o1) %e^(5*x) = 0.5
> (%i2) solve(EQ, x);
>
> rat: replaced -0.5 by -1/2 = -0.5
> (%o2) [x = log(%e^(2*%i*%pi/5)/2^(1/5)),x = log(%e^(4*%i*%pi/5)/2^(1/5)),
>        x = -(log(2)+4*%i*%pi)/5,x = -(log(2)+2*%i*%pi)/5,x = -log(2)/5]
> (%i3) declare(x, real);
>
> (%o3) done
> (%i4) solve(EQ, x);
>
> rat: replaced -0.5 by -1/2 = -0.5
> (%o4) [x = log(%e^(2*%i*%pi/5)/2^(1/5)),x = log(%e^(4*%i*%pi/5)/2^(1/5)),
>        x = -(log(2)+4*%i*%pi)/5,x = -(log(2)+2*%i*%pi)/5,x = -log(2)/5]
>
> You can see that the solution not only gives the real value but also the
> logs of the complex fifth roots of 1 added to it. If you want complex
> solutions this is of course correct. Unfortunately declaring x real
> doesn't help. Apparently solve doesn't honor this. When the constant is
> getting large, like in exp(x*1e9), there will be 1 billion solutions
> generated which just takes too much time.

(Variants of) this question seem to get asked quite frequently. If I
understand it correctly, the problem is that it's not very easy to
select "just real solutions" in general. For example, I happen to know
that

  -3*%i*(1+%i)^2

is six (mainly since it came from gcfactor(6)), which is real. But
that's not so obvious at first glance. Suppose that solve ends up with
some big list of complicated expressions with complex numbers in
them. How should it decide which one is real?

In the example you give, this can be sidestepped by using log():

  (%i1) EQ: exp(x*5) = 1/2;

  (%o1) %e^(5*x) = 1/2
  (%i2) log(EQ);

  (%o2) 5*x = -log(2)
  (%i3) first(solve(%, x));

  (%o3) x = -log(2)/5
  (%i4) float(%);

  (%o4) x = -.1386294361119891

Note that I used 1/2 rather than 0.5 in the equation to solve.

It seems that solve approaches the problem by finding solutions to
(exp(x))^5 = 1/2 (which has 5 solutions in a circle about zero, four
complex and one real and positive) and then applies log to each.


Rupert
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 315 bytes
Desc: not available
URL: <http://www.math.utexas.edu/pipermail/maxima/attachments/20121025/94035d61/attachment.pgp>;