如何使用蒙特卡洛方法来找到值的不确定性?

时间:2018-12-02 14:31:55

标签: python math physics montecarlo

我正在尝试使用蒙特卡洛模拟来求解物理方程,我知道这很长(我只需要用它来学习它即可)。

我大约有5个值,一个是时间,每个值都有随机不确定性(错误)。就像质量是(10 +-0.1)kg,误差是0.1 kg

例如,如果我进行了5,000次此实验,我实际上如何找到测量的分布?

我知道我可以制造2个错误数组,并且可以将它们放入函数中。但是我该怎么办呢?我是否将误差放在等式中,然后将答案添加到数组中,然后将更改后的数组值放入等式中,并重复一千次。还是我实际上是计算实际值并将其添加到数组中。

请帮助我理解这一点。

编辑:

我遇到的问题基本上是一个密度ds的球体通过密度dl的液体在时间t内下降了距离l,这符合粘度方程,我需要找到粘度测量值的分布。

等式无关紧要,无论我拥有什么等式,我都应该能够使用这样的方法来找到测量值的分布。天气我要从窗户或其他地方丢球。

2 个答案:

答案 0 :(得分:0)

基本的蒙特卡洛非常简单。以下内容可能会帮助您入门:

import random,statistics,math

#The following function generates a
#random observation of f(x) where
#x is a vector of independent normal variables
#whose means are given by the vector mus
#and whose standard deviations are given by sigmas

def sample(f,mus,sigmas):
    x = (random.gauss(m,s) for m,s in zip(mus,sigmas))
    return f(*x)

#do n times, returning the sample mean and standard deviation:

def monte_carlo(f,mus,sigmas,n):
    samples = [sample(f,mus,sigmas) for _ in range(n)]
    return (statistics.mean(samples), statistics.stdev(samples))

#for testing purposes:

def V(r,h):
    return math.pi*r**2*h

print(monte_carlo(V,(2,4),(0.02, 0.01),1000))

输出:

(50.2497301631037, 1.0215188736786902)

答案 1 :(得分:0)

好吧,让我们尝试一个简单的例子-您有气枪以质量m和速度v射击球。你必须测量动能

E = m * v 2 / 2

速度分布-高斯,平均值为10,标准偏差为1。

存在质量分布-但是我们不能做高斯分布,假设它被截断了正态,下限为1,因此没有负值,loc等于5,小数位数等于3

所以我们要做的是-采样速度,样品质量,使用它们来查找动能,进行多次,建立能量分布,获取平均值,获取标准偏差,绘制图形等

一些简单的Python代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import truncnorm

def sampleMass(n, low, high, mu, sigma):
    """
    Sample n mass values from truncated normal
    """
    tn = truncnorm(low, high, loc=mu, scale=sigma)
    return tn.rvs(n)

def sampleVelocity(n, mu, sigma):
    return np.random.normal(loc = mu, scale = sigma, size=n)


mass_low  = 1.
mass_high = 1000.
mass_mu   = 5.
mass_sigma = 3.0

vel_mu    = 10.0
vel_sigma = 1.0

nof_trials = 100000

mass = sampleMass(nof_trials, mass_low, mass_high, mass_mu, mass_sigma) # get samples of mass
vel  = sampleVelocity(nof_trials, vel_mu, vel_sigma) # get samples of velocity

kinenergy = 0.5 * mass * vel*vel # distribution of kinetic energy

print("Mean value and stddev of the final distribution")
print(np.mean(kinenergy))
print(np.std(kinenergy))

print("Min/max values of the final distribution")
print(np.min(kinenergy))
print(np.max(kinenergy))


# print histogram of the distribution
n, bins, patches = plt.hist(kinenergy, 100, density=True, facecolor='green', alpha=0.75)

plt.xlabel('Energy')
plt.ylabel('Probability')
plt.title('Kinetic energy distribution')
plt.grid(True)

plt.show()

具有类似输出

Mean value and stddev of the final distribution
483.8162951263243
118.34049421853899
Min/max values of the final distribution
128.86671038372
1391.400187563612

enter image description here