【问题标题】:Efficient way for calculating integrals?计算积分的有效方法?
【发布时间】:2018-05-17 15:38:55
【问题描述】:

我知道如何使用 Monte-Carlo 来计算积分,但我想知道是否可以使用梯形规则结合 numpy 来提高效率以获得相同的积分,我不确定哪个最快或后者可能吗?

例如整合e**-x**2 > y 我可以像这样使用蒙特卡罗方法:

import numpy as np
import matplotlib.pyplot as plt

X = np.random.rand(500000,2)
X[:,0] = X[:,0]*4-2
J = np.where(X[:,1] < np.exp(-X[:,0]**2))[0]
Xp = X[:2000]
Ip = [i for i in range(len(Xp)) if i in J]
Inp = [i for i in range(len(Xp)) if i not in J]
plt.plot(Xp[Ip,0],Xp[Ip,1], 'bd', Xp[Inp,0],Xp[Inp,1], 'rd')
plt.show()

这可以很容易地计算出来:

print len(J) / 500000.0 * 4

这给出了:

1.767784

在这种情况下,这很容易,但是如果没有像[a,b] , n 那样指定间隔,并且我想创建一个函数,那么我认为上面的方法并不是很有效,至少我是这么认为的。

所以,我的问题是,我能否在具有梯形规则的函数中集成一个连续函数,例如cos(x)/x,并在一个确定的区间内,如[a,b]?

它比我这里使用的方法更好吗?

欢迎任何建议。

【问题讨论】:

  • 嗯,不,使用 Monte-Carlo 将一维、有界、无限可微函数与快速衰减的导数集成确实是一个非常的坏主意。但是你从哪里得到梯形规则也不是完全垃圾的想法?数值积分有很多更好的方法。 scipy.integrate 怎么了?
  • @AndreyTyukin 我还是个编程初学者,其他方法我发现使用了太多新命令来理解,所以我从最简单的atm开始,但是如果你推荐任何一种方法我是听。
  • “非常初学者”是相对的......普通的“初学者”能够实现用于计算积分的蒙特卡罗方法并不明显。它也不是特定于编程的。

标签: python python-2.7 numpy integral


【解决方案1】:

只需使用scipy.integrate.quad:

from scipy import integrate
from np import inf
from math import exp, sqrt, pi

res, errEstimate = integrate.quad(lambda x: exp(-x**2), -inf, +inf)

print(res)       #output: 1.7724538509055159
print(sqrt(pi))  #output: 1.7724538509055159

最后一行只是检查计算的积分确实是 Pi 的平方根(它是 Gaussian integral)。

【讨论】:

    【解决方案2】:

    您也可以使用黎曼近似。下面的代码是Java

    package math;
    
    import java.util.Optional;
    import java.util.function.*;
    import java.util.stream.IntStream;
    import static java.lang.Math.*;
    
    public class IntegralJava8
    {
        public interface Riemann extends BiFunction<Function<Double, Double>, Integer, 
        BinaryOperator<Double>> { }
    
        public static void main(String args[])
        {
            int N=100000;
            Riemann s = (f, n) -> (a, b) -> 
            IntStream.range(0, n)
            .mapToDouble(i -> f.apply(a + i * ((b - a) / n)) * ((b - a) / n)).sum();
            Optional<Double> gaussIntegral = 
                Optional.of(s.apply(x -> exp(-pow(x, 2)), N).apply(-1000.0, 1000.0));
            gaussIntegral.ifPresent(System.out::println);
        }
    }
    

    在上面的类中,它将计算从-infinity到infinity的高斯积分,等于PI的平方根(1.772)

    【讨论】:

      猜你喜欢
      • 2017-05-13
      • 2011-06-07
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多