简体   繁体   English

尝试在 Python 中使用辛普森定律

[英]Trying to use Simpson's Law in Python

I am trying to write a program about Simpson's Law.What I am trying to do is use as error as shown in this picture:我正在尝试编写有关辛普森定律的程序。我正在尝试做的是用作错误,如图所示:

. .

In the code i write the Ih is my f1 and Ih/2 is my f2.If the error doesnt happen then the steps get halved.在我写的代码中,Ih 是我的 f1,Ih/2 是我的 f2。如果错误没有发生,那么步骤就会减半。

However I get this error但是我得到这个错误

Traceback (most recent call last):
  File "C:\Users\Egw\Desktop\Analysh\Askhsh1\example.py", line 22, in <module>
    sim2 = simps(f2, x2)
  File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 436, in simps
    return simpson(y, x=x, dx=dx, axis=axis, even=even)
  File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 542, in simpson
    last_dx = x[slice1] - x[slice2]
IndexError: index -1 is out of bounds for axis 0 with size 0

Process finished with exit code 1

My code is我的代码是

import numpy as np
from sympy import *
from scipy.integrate import simps

a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)

while True:
    x1 = np.linspace(a, b, N)
    f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
    sim1 = simps(f1, x1)
    x2 = np.linspace(a, b, int(N/2))
    f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
    sim2 = simps(f2, x2)
    if abs(sim1 - sim2) < error:
        break
    else:
        N = int(N/2)

print(sim1)

I wasnt expecting any error,and basically expecting to calculate correctly.我没有预料到任何错误,并且基本上期望能够正确计算。

When you reduce the grid step by half h -> h/2, the number of grid steps in turn grows N -> 2 * N, so you have to make two changes in your code:当您将网格步数减少一半 h -> h/2 时,网格步数依次增加 N -> 2 * N,因此您必须在代码中进行两处更改:

  1. Define x2 to have twice as many elements as x1定义 x2 的元素数量是 x1 的两倍
   x2 = np.linspace(a, b, 2 * N)
  1. Update N to be twice it was on the previous iteration将 N 更新为上一次迭代的两倍
        N = 2 * N

The resulting code would be结果代码将是

import numpy as np
from sympy import *
from scipy.integrate import simps

a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)

while True:
    x1 = np.linspace(a, b, N)
    f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
    sim1 = simps(f1, x1)
    x2 = np.linspace(a, b, 2 * N)
    f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
    sim2 = simps(f2, x2)
    if abs(sim1 - sim2) < error:
        break
    else:
        N = 2 * N

print(sim1)

And this prints the value这会打印出价值

87.9765411043221

with error consistent with the threshold误差与阈值一致

abs(sim1 - sim2) = 4.66441463231604e-9

@DmitriChubarov's solution is correct. @DmitriChubarov 的解决方案是正确的。 However, your implementation is very inefficient: it does double the work it needs to.但是,您的实施效率非常低:它完成了所需工作的两倍。 Also, simps is deprecated, you should be using proper exponential notation, and your function expression can be simplified.此外,不推荐使用simps ,您应该使用正确的指数表示法,并且可以简化您的 function 表达式。 For an equivalent error-free algorithm that still doubles the input array length on each iteration but doesn't throw away the intermediate result,对于在每次迭代中仍将输入数组长度加倍但不丢弃中间结果的等效无错误算法,

import numpy as np
from scipy.integrate import simpson

a = 0
b = 2*np.pi
N = 100
ra = 0.1  # ρα
R = 0.05
fa = np.radians(35)  # φα
za = 0.4
aa = np.linalg.norm((ra, R, za))
error = 5e-9
sim1 = np.nan

while True:
    x = np.linspace(a, b, N)
    f = (aa**2 - 2*ra*R*np.cos(x - fa))**-1.5
    sim2 = simpson(f, x)

    if np.abs(sim1 - sim2) < error:
        break
    sim1 = sim2
    N *= 2

print(sim1)

When I modified your code by adding two lines to print(len(x1), len(f1)) and print(len(x2), len(f2)) , I got these results:当我通过向print(len(x1), len(f1))print(len(x2), len(f2))添加两行来修改您的代码时,我得到了这些结果:

Output: Output:

length of x1 and f1: 100 100
length of x2 and f2: 50 50 

length of x1 and f1: 50 50
length of x2 and f2: 25 25 

length of x1 and f1: 25 25
length of x2 and f2: 12 12 

length of x1 and f1: 12 12
length of x2 and f2: 6 6 

length of x1 and f1: 6 6
length of x2 and f2: 3 3 

length of x1 and f1: 3 3
length of x2 and f2: 1 1 

length of x1 and f1: 1 1
length of x2 and f2: 0 0 

as you can see the length decreases each loop because N decreases and ends with an empty list length of x2 and f2: 0 0 and this causes the error you have had.如您所见,每个循环的长度都会减少,因为N会减少并以length of x2 and f2: 0 0结束,这会导致您遇到错误。 To fix the issue of 'the empty list' I suggest that you duplicate N;要解决“空列表”的问题,我建议您复制 N; this means using N*2 instead of N/2 .这意味着使用N*2而不是N/2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM