【问题标题】:Python fsolve does not take array of floats. How to implement it?Python fsolve 不采用浮点数组。如何实施?
【发布时间】:2015-02-13 05:36:43
【问题描述】:

我使用 fsolve 来找到示例 sinus 函数的零点,效果很好。但是,我想对数据集做同样的事情。两个浮点数列表,后来转换为具有 numpy.asarray() 的数组,包含 (x,y) 值,即 't' 和 'ys'。

虽然我找到了一些related questions,但我未能实现其中提供的代码,正如我尝试在这里展示的那样。我们感兴趣的数组存储在 2D 列表中(data[i][j],其中 'i' 对应于一个变量(例如 data[0]==t==time==x 值),而 'j' 是沿 x 轴的所述变量的值(例如 data[1]==Force)。请记住,每个 data[i] 都是浮点数组。

您能否提供一个示例代码,它接受两个输入(提到的两个数组)并返回其交点与定义的函数(例如'y=0')。

我包含了我对其他相关问题所做的一些测试。 (@HYRY 的回答)

我认为这无关紧要,但我通过 Anaconda 使用 Spyder

提前致谢!

"""
Following the answer provided by @HYRY in the 'related questions' (see link above).
At this point of the code, the variable 'data' has already been defined as stated before.
"""
from scipy.optimize import fsolve

def tfun(x):
    return data[0][x]

def yfun(x):
    return data[14][x]

def findIntersection(fun1, fun2, x0):
    return [fsolve(lambda x:fun1(x)-fun2(x, y), x0) for y in range(1, 10)]

print findIntersection(tfun, yfun, 0)

返回下一个错误

  File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 36, in tfun
    return data[0][x]

IndexError: arrays used as indices must be of integer (or boolean) type

完整输出如下:

Traceback (most recent call last):

  File "<ipython-input-16-105803b235a9>", line 1, in <module>
    runfile('E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py', wdir='E:/Data/Anaconda/[...]/00-Latest')

  File "C:\Anaconda\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 580, in runfile
    execfile(filename, namespace)

  File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 44, in <module>
    print findIntersection(tfun, yfun, 0)

  File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 42, in findIntersection
    return [fsolve(lambda x:fun1(x)-fun2(x, y), x0) for y in range(1, 10)]

  File "C:\Anaconda\lib\site-packages\scipy\optimize\minpack.py", line 140, in fsolve
    res = _root_hybr(func, x0, args, jac=fprime, **options)

  File "C:\Anaconda\lib\site-packages\scipy\optimize\minpack.py", line 209, in _root_hybr
    ml, mu, epsfcn, factor, diag)

  File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 42, in <lambda>
    return [fsolve(lambda x:fun1(x)-fun2(x, y), x0) for y in range(1, 10)]

  File "E:/Data/Anaconda/[...]/00-Latest/fsolvestacktest001.py", line 36, in tfun
    return data[0][x]

IndexError: arrays used as indices must be of integer (or boolean) type

【问题讨论】:

  • 您能否详细说明一下您尝试使用相关问题中的代码时发生了什么?不是完整的堆栈跟踪之类的,只是为了说明它可能不起作用的原因。
  • 已编辑。希望现在更清晰了。
  • 您正在使用x 索引一个数组,这是一个浮点数组。浮点数作为数组索引没有意义。
  • 另外,yfunxy 的函数,但y 没有被使用。
  • 刚刚意识到并编辑了它。好了,我懂了。所以我可以应用 round 或 math.floor 或其他函数/方法。然而,这并不能解决问题。我添加了这个示例,但它可能无法直接解决问题。如前所述,这就是如何找到一个数据集和一个函数或两个数据集之间的交集,因为我们可以很容易地定义一个充满零的数组。

标签: python arrays python-2.7 numpy scipy


【解决方案1】:

您可以通过插值将数据集(数组)“转换”为连续函数。 scipy.interpolate.interp1d 是一个为您提供结果函数的工厂,然后您可以将其与根查找算法一起使用。 --edit-- 从 20 个样本计算 sin 和 cos 交集的示例(我使用了三次样条插值,因为分段线性会发出关于平滑度的警告):

>>> import numpy, scipy.optimize, scipy.interpolate
>>> x = numpy.linspace(0,2*numpy.pi, 20)
>>> x
array([ 0.        ,  0.33069396,  0.66138793,  0.99208189,  1.32277585,
    1.65346982,  1.98416378,  2.31485774,  2.64555171,  2.97624567,
    3.30693964,  3.6376336 ,  3.96832756,  4.29902153,  4.62971549,
    4.96040945,  5.29110342,  5.62179738,  5.95249134,  6.28318531])
>>> y1sampled = numpy.sin(x)
>>> y2sampled = numpy.cos(x)
>>> y1int = scipy.interpolate.interp1d(x,y1sampled,kind='cubic')
>>> y2int = scipy.interpolate.interp1d(x,y2sampled,kind='cubic')
>>> scipy.optimize.fsolve(lambda x: y1int(x) - y2int(x), numpy.pi)
array([ 3.9269884])
>>> scipy.optimize.fsolve(lambda x: numpy.sin(x) - numpy.cos(x), numpy.pi)
array([ 3.92699082])

请注意,插值会让您“猜测”采样点之间应该包含哪些数据。没有办法说这些猜测有多好。 (但对于我的例子,你可以看到这是一个很好的估计)

【讨论】:

  • 这似乎回答了这个问题。我将在接下来的几周内制作一些示例来展示此功能,以完成答案。
  • 非常感谢您提供的示例。对我来说,现在它似乎完成了。我猜想精度本质上与 x 采样值之间的间距以及 y 值与 x 轴间距的相对变化有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多