我正在尝试用sci-py中的盆地跳跃算法来最小化函数。这是我的代码:
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))
完整错误读取
回溯(最近一次调用最后一次):文件“anneal.py”,第14行,在estimator1 = gmpy2.div(x0,s)-gmpy2.sqrt(((pow(x0,s)/ 4)-b ))TypeError:不支持div()参数类型
我基本上想要实现的目标是最小化abs((c*d)-e)
,但我收到的错误为:TypeError: div() argument types not supported
。我已经用Google搜索了这个错误,可能原因是变量和列表之间的类型不匹配。所以我的问题是我应该如何重新制定estimator1
和estimator2
以便能够将其传递给水池跳跃最小化器。
编辑:
更正后的代码现在读取(也删除了不必要的导入):
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))
答案 0 :(得分:0)
我认为问题在于你将python list
传入gmpy2.div
。 C
代码会检查int
,rational
,real
和complex
,如果这些代码都不适合,则会引发您提到的错误。尝试将x0
作为int传递。
此外,我不认为scipy
会对您传入的mpz(2)
感到高兴,scipy
通常适用于python lists
,scipy.sparse
矩阵或密集numpy.ndarray
s。
在python中处理大数字方面,int
是无界的(https://docs.python.org/3.6/library/stdtypes.html#typesnumeric)。当你需要数值稳定的操作时,NumPy也是一个很好看的地方,numpy拥有64位float
和int
以及128位复数的自有类型系统。