来自Mathematica和Python的超越方程的解与

时间:2017-04-04 15:59:50

标签: python numpy wolfram-mathematica root

我正在解决一个超越方程组:

  1. cos(x) / x = 0.48283 + a*3.46891
  2. cos(y) / y = 0.47814 + b*28.6418
  3. a + b = 1
  4. 1.02 * sinc(x) = 1.03 * sinc(y)
  5. 就是这样,我尝试用两种独立的编程语言(Mathematica和Python)解决上述系统

    数学

    运行代码

    FindRoot[{Cos[x]/x == 0.482828 + a*3.46891, 
      Cos[y]/y == 0.47814 + b*28.6418, a + b == 1, 
      1.02*Sinc[x] == 1.03*Sinc[y]}, {{x, .2}, {y, .2}, {a, 0.3}, {b, 
       0.3}}, PrecisionGoal -> 6]
    

    返回

    {x -> 0.261727, y -> 0.355888, a -> 0.924737, b -> 0.0752628}
    

    的Python

    运行代码:

    import numpy as np
    from scipy.optimize import root
    
    def fuuu(X, en,dv,tri,sti):
            x, y, a, b = X
    
            F = [np.cos(x) / x - en-a*dv,
                 np.cos(y) / y - tri-b*sti,
                 a + b - 1,
                 1.02 * np.sinc(x) - 1.03 * np.sinc(y)]
    
            return F
        root(fuuu, [0.2, 0.2, 0.3, 0.3], args=(0.482828,3.46891,0.47814,28.6418)).x
    

    返回

    array([ 0.26843418,  0.27872813,  0.89626625,  0.10373375])
    

    比较

    让我们说' x'价值是一样的。让我们忽略这个微小的差异。但y值相差几英里!物理意义完全改变。出于某种原因,我相信Mathematica的价值超过了我相信来自Python的价值。

    问题:

    1. 为什么计算不同?
    2. 哪一个现在正确?我需要在python中更改什么(假设python是有问题的?)

1 个答案:

答案 0 :(得分:7)

由于sinc函数,计算方法不同。

(* Mathematica *)
In[1] := Sinc[0.26843418]
Out[1] = 0.988034

# Python
>>> np.sinc(0.26843418)
0.88561519683835599
>>> np.sin(0.26843418) / 0.26843418
0.98803370932709034

咦?那么let's RTFM

  

numpy.sinc(x)的

     

返回sinc函数。

     

sinc函数是sin(πx)/(πx)。

糟糕。 NumPy的sinc有一个different definition而不是Mathematica的Sinc

  • Mathematica的Sinc使用非标准化定义sin(x)/ x。这个定义通常用于数学和物理学。
  • NumPy的sinc使用规范化版本sin(πx)/(πx)。该定义通常用于数字信号处理和信息理论。它被称为归一化,因为
    -∞ sin(πx)/(πx)dx = 1.

因此,如果您希望NumPy产生与Mathematica相同的结果,则需要将xy除以np.pi

def fuuu(X, en,dv,tri,sti):
    x, y, a, b = X
    F = [np.cos(x) / x - en-a*dv,
         np.cos(y) / y - tri-b*sti,
         a + b - 1,
         1.02 * np.sinc(x/np.pi) - 1.03 * np.sinc(y/np.pi)]    # <---
    return F
>>> root(fuuu, [0.2, 0.2, 0.3, 0.3], args=(0.482828,3.46891,0.47814,28.6418)).x
array([ 0.26172691,  0.3558877 ,  0.92473722,  0.07526278])