我正在尝试使用蒙特卡洛模拟来求解物理方程,我知道这很长(我只需要用它来学习它即可)。
我大约有5个值,一个是时间,每个值都有随机不确定性(错误)。就像质量是(10 +-0.1)kg,误差是0.1 kg
例如,如果我进行了5,000次此实验,我实际上如何找到测量的分布?
我知道我可以制造2个错误数组,并且可以将它们放入函数中。但是我该怎么办呢?我是否将误差放在等式中,然后将答案添加到数组中,然后将更改后的数组值放入等式中,并重复一千次。还是我实际上是计算实际值并将其添加到数组中。
请帮助我理解这一点。
我遇到的问题基本上是一个密度ds的球体通过密度dl的液体在时间t内下降了距离l,这符合粘度方程,我需要找到粘度测量值的分布。
等式无关紧要,无论我拥有什么等式,我都应该能够使用这样的方法来找到测量值的分布。天气我要从窗户或其他地方丢球。
答案 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