8

I want to do a root search for the following nonlinear equations, I do it in Python but it doesn't work. my code is below

from pylab import *
import scipy
import scipy.optimize

def z1(x,y):
    temp=1+1j+x+2*y;
    return temp

def z2(x,y):
    temp=-1j-2*x+sqrt(3)*y;
    return temp

def func(x):
    temp=[z1(x[0],x[1])-1.0/(1-1.0/(z2(x[0],x[1]))),1-2.0/(z2(x[0],x[1])-4.0/z1(x[0],x[1]))]
    return temp

result=scipy.optimize.fsolve(func,[1+1j,1+1j])

print result

when I run it, it shows errors:

---> 30 result=scipy.optimize.fsolve(func,[1+1j,1+1j])

C:\Python27\lib\site-packages\scipy\optimize\minpack.py in fsolve(func, x0, args, fprime, full_output, col_deriv, xtol, maxfev, band, epsfcn, factor, diag)

123             maxfev = 200*(n + 1)

124         retval = _minpack._hybrd(func, x0, args, full_output, xtol,

--> 125 maxfev, ml, mu, epsfcn, factor, diag)

126     else:

127         _check_func('fsolve', 'fprime', Dfun, x0, args, n, (n,n))
user2133730
  • 81
  • 1
  • 1
  • 3
  • it is due to the complex number unit "j", it seems fsolve can only search root for real equations and return real roots??! – user2133730 Mar 05 '13 at 00:28

2 Answers2

6

fsolve finds zeros of functions from R^n -> R. The similar function root finds zeros of functions from R^n -> R^m.

It looks like you're trying to find zeros of a function from C^2 -> C^2, which as far as I know scipy.optimize doesn't support directly - but you could try writing it a function from R^4 -> R^4 and then using root. For example, something along the lines of:

def func_as_reals(x):
    r1, c1, r2, c2 = x
    a, b = func([complex(r1, c1), complex(r2, c2)])
    return [a.real, a.imag, b.real, b.imag]

should work, though it might be significantly faster to do it directly on the real numbers instead of repeatedly wrapping into complex and unwrapping.

Danica
  • 28,423
  • 6
  • 90
  • 122
  • This is just an extremely simplified example for my real-solving problem. The real problem is a 5000 depth "fibonacci-like" fraction, but in C^2, so it seems no hope to rewrite that monster into R^4 – user2133730 Mar 05 '13 at 00:42
  • by the way, why there is no .root under .optimize ? when I "tab" optimize. I can find .fsolve but there is no .root . I use Python27, academic version – user2133730 Mar 05 '13 at 00:46
  • What version of scipy do you have? `root` is new in 0.11, as the linked documentation says; since it seems like you're probably using EPD (since there's no such thing as an "academic version" of Python), it might still have an old version. – Danica Mar 05 '13 at 04:40
  • Of course, a point `x` is a zero of `f : R^n -> R^m` iff `|| f(x) || = 0`. So you could try `fsolve`ing the function that's like `func_as_reals` but instead returns `a.real**2 + a.imag**2 + b.real**2 + b.imag**2` instead. – Danica Mar 05 '13 at 06:03
4

You could try mpmath's findroot(sympy):

from mpmath import findroot

#Your code here

ans = findroot([z1,z2],(0,0))
print(ans)

Returns:

[(-0.302169479251962 - 0.651084739625981j)]
[(-0.348915260374019 - 0.174457630187009j)]

which is a solution of your system.
Mpmath is a multiprecision library so it's routines are generally slower, but you could give it a try!

Javier Garcia
  • 539
  • 1
  • 4
  • 15