-1

I'm trying to minimize a function with basin-hopping algorithm in sci-py. Here is my code:

from math import *
import time
import gmpy2
from gmpy2 import mpz
from gmpy2 import mpq,mpfr,mpc
import numpy as np
from scipy.optimize import basinhopping
minimizer_kwargs = {"method": "BFGS"}


s=mpz('2')
x0=[153000]
b = mpfr('6097781399')
estimator1=gmpy2.div(x0, s)-gmpy2.sqrt(((pow(x0,s)/4)-b))
estimator2=gmpy2.div(x0, s)+gmpy2.sqrt(((pow(x0,s)/4)-b))

c=mpfr(estimator1)
d=mpfr(estimator2)
e=mpz(b)

func = lambda x: abs((c*d)-e)

ret = basinhopping(func, x0, minimizer_kwargs=minimizer_kwargs,
niter=400)
print("global minimum: x = %.4f, f(x0) = %.4f" % (ret.x, ret.fun))

the full error reads

Traceback (most recent call last): File "anneal.py", line 14, in estimator1=gmpy2.div(x0, s)-gmpy2.sqrt(((pow(x0,s)/4)-b)) TypeError: div() argument types not supported

What I'm basically trying to achieve is minimizing abs((c*d)-e), however I get an error as: TypeError: div() argument types not supported. I have Googled about this error and perhaps the cause of this is a type mismatch between a variable and a list. So my question is how should I re-formulate estimator1 and estimator2 to be able to pass it into basin-hopping minimizer.

Edit:

Corrected code now reads (also removed unnecessary imports):

from math import *
from scipy.optimize import basinhopping
minimizer_kwargs = {"method": "BFGS"}
def f(x):

    b = 6097781399
    estimator1=(x/2)-sqrt(abs((pow(x,2)/4)-b))
    estimator2=(x/2)+sqrt(abs((pow(x,2)/4)-b))
    return abs((estimator1*estimator2)-b)

x = 110000
ret = basinhopping(f, x, minimizer_kwargs=minimizer_kwargs,
niter=2000)
print("global minimum: x = %.4f, f(x0) = %.4f" % (ret.x, ret.fun))
Georgy
  • 6,348
  • 7
  • 46
  • 58
msalperen
  • 113
  • 8
  • can you post the full error? – Matti Lyra Jun 11 '17 at 18:33
  • Traceback (most recent call last): File "C:\Users\msalperen\Desktop\anneal.py", line 14, in estimator1=gmpy2.div(x0, s)-gmpy2.sqrt(((pow(x0,s)/4)-b)) TypeError: div() argument types not supported – msalperen Jun 11 '17 at 18:43
  • I think the problem is that you're passing in a python `list` into `gmpy2.div`. The `C` code checks for int, rational, real and complex and if none of those fits it throws the error you mentioned. Have you tried passing in `x0` as an `int`? – Matti Lyra Jun 11 '17 at 19:00
  • I have removed the brackets around x0 and this time I get: "TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''" – msalperen Jun 11 '17 at 19:32
  • ok, now you're getting an error from `numpy` not from `gmpy2` anymore. Have you checked that you can even use the `mpz` data type in `scipy` functions? I'd be surprised if that just works – Matti Lyra Jun 11 '17 at 19:37
  • I have removed all the references to gmpy, mpz and mpfr; and the formulae now looks like : estimator1=(x0/2)-sqrt(abs((pow(x0,2)/4)-b)) and estimator2=(x0/2)+sqrt(abs((pow(x0,2)/4)-b)). This returns a result but it always returns the original(predefiined) x0 as the global minimum. I think I should read more about scipy documentation on this issue, but at least I got rid of errors. Any suggestions beyond this, on how to work on large numbers together with scipy and how to get acceptable global minima are welcome. Thanks. – msalperen Jun 11 '17 at 20:00
  • see my answer below – Matti Lyra Jun 12 '17 at 09:03

1 Answers1

0

I think the problem is that you're passing in a python list into gmpy2.div. The C code checks for int, rational, real and complex and if none of those fits it throws the error you mentioned. Try passing in x0 as an int.

Further I don't think scipy will be too happy about the mpz(2) you're passing in, scipy usually works with either python lists, scipy.sparse matrices or dense numpy.ndarrays.

In terms of handling large numbers in python, the ints are unbounded (https://docs.python.org/3.6/library/stdtypes.html#typesnumeric). NumPy is also a good place to look when you need numerically stable operations, numpy has it's own type system with 64bit floats and ints and 128 bit complex numbers.

https://docs.scipy.org/doc/numpy/user/basics.types.html

Matti Lyra
  • 11,850
  • 6
  • 43
  • 64
  • I have defined my variables in a function and initial value outside that function. Now it seems to work (I have inserted an updated code above for further reference). Thanks. – msalperen Jun 12 '17 at 20:22