计算物理专题----蒙特卡洛积分实战

news2025/6/7 23:19:49

Part one 蒙特卡洛积分计算案例

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.stats import norm, kstest

np.random.seed(0)
def integrate(a,b,n=100):
    x = np.random.uniform(a,b,n)
    total = sum(np.exp(x))
    return (b - a) * total / n



Num = 10000
F = np.zeros(Num)
for i in range(Num):
    result = integrate(0,1) 
    F[i] = result    
df = pd.DataFrame({'score':F})
bins = np.arange(1.61,1.83,0.001)  # 箱的边界值
df['score_bin'] = pd.cut(df['score'], bins)
count = df['score_bin'].value_counts()
x = [(i.left + i.right) / 2 for i in count.index]
y = count.values/sum(count.values)
# 绘制散点图
plt.scatter(x,y,s=1,c="green",label="10000 I(100) calcs")

F = np.zeros(Num)
for i in range(Num):
    result = integrate(0,1,n=500) 
    F[i] = result    
df = pd.DataFrame({'score':F})
bins = np.arange(1.61,1.83,0.001)  # 箱的边界值
df['score_bin'] = pd.cut(df['score'], bins)
count = df['score_bin'].value_counts()
x = [(i.left + i.right) / 2 for i in count.index]
y = count.values/sum(count.values)
# 绘制散点图
plt.scatter(x,y,s=1,c="red",label="10000 I(500) calcs")

F = np.zeros(Num)
for i in range(Num):
    result = integrate(0,1,n=1000) 
    F[i] = result    
df = pd.DataFrame({'score':F})
bins = np.arange(1.61,1.83,0.001)  # 箱的边界值
df['score_bin'] = pd.cut(df['score'], bins)
count = df['score_bin'].value_counts()
x = [(i.left + i.right) / 2 for i in count.index]
y = count.values/sum(count.values)
# 绘制散点图
plt.scatter(x,y,s=1,c="blue",label="10000 I(1000) calcs")

########

##Num = 100000
##F = np.zeros(Num)
##for i in range(Num):
##    result = integrate(0,1) 
##    F[i] = result    
##df = pd.DataFrame({'score':F})
##bins = np.arange(1.61,1.83,0.001)  # 箱的边界值
##df['score_bin'] = pd.cut(df['score'], bins)
##count = df['score_bin'].value_counts()
##x = [(i.left + i.right) / 2 for i in count.index]
##y = count.values/sum(count.values)
##plt.scatter(x,y,s=1,c="red",label="10000 I calcs")
####


plt.legend()
plt.savefig("hist-plot-4.jpg")
plt.show()
##print(count)
##import csv
##header = ["fit"]
##rows = [[i] for i in F]
##
##with open('1.csv','w',newline="") as file:
##    writer = csv.writer(file)
##    writer.writerow(header)
##    writer.writerows(rows)

Final Result:1.718

Real Result: 1.71828

ERROR EASTIMATE:10^-4

  • 蒙特卡洛方法的误差通常可以通过增加模拟次数来减小。具体来说,当我们重复运行模拟并计算出相应的输出后,我们可以计算这些输出的均值和方差,并根据这些数据来估计误差值。如果我们希望减小误差,可以增加模拟次数,这样均值和方差都会更加准确,从而使误差更小。

Part 2 重要抽样 分层抽样

        重要抽样积分和分层抽样积分是数值积分中常用的两种方法,以获得更精确的结果。

        重要性抽样积分涉及从不同于原始分布的概率分布中抽样,但对最终结果贡献较大的区域赋予更大的权重。换句话说,该算法选择更有可能对积分结果做出贡献的样本,并赋予它们比其他样本更高的权重。当原始分布难以采样或对最终结果贡献最大的区域很小时,这尤其有用。

        例如,考虑f(x)从a到b的积分。我们可以从与f(x)|成比例的分布中抽样,而不是从区间[a,b]中均匀抽样。这意味着具有较高的|f(x)|值的区域将被更频繁地采样,并在最终结果中被赋予更高的权重。

        分层采样整合则是将整合区域划分为若干子区域,并从每个子区域分别采集样本。这确保了所有区域的采样都是平等的,而不管该区域的被积数的值是多少。

        例如,考虑f(x,y)在区域[a,b] x [c,d]上的积分。我们可以把这个区域分成4个更小的区域,每个区域分别采样。这确保了我们从所有区域得到相等的样本,当被积量在积分区域上表现出高方差时特别有用。

        重要抽样积分和分层抽样积分都是数值积分的重要技术,它们的适用性取决于需要解决的问题。在被积量高度可变或难以采样的情况下,重要性抽样往往更有效,而分层抽样在被积量在整个积分区域表现出高度可变性的情况下是有用的。

        我们将a,b两问的结果用下表展示处理

Num = 5e4,k=5e3,n=10

Simple MC

Stratified sampling

Round 1

1.3741162994281273

1.3741162994281273

Stats(round for 200)

figure

mean

1.3873987598712592

1.387267505078644

std

0.022234190779851584

0.02282746853161396

find the optimal n

Optimal

RESULT

ERROR

N=18

1.3868879367871603

1e-4

import numpy as np
np.random.seed(0)

#exact value 1.38629
def MC(a=0,b=1,n=50000):
    f = lambda x:1/(x+x**0.5)
    x = np.random.uniform(a,b,n)
    return sum(f(x))*(b-a)/n

#stratified sampling
def SS(a=0,b=1,n=10,k=5000):
    x1 = np.linspace(a,b,k+1)[:k]
    x2 = np.linspace(a,b,k+1)[1:]
    SUM = 0
    for i in range(k):
        SUM += MC(a=x1[i],b=x2[i],n=n)
    return SUM

import matplotlib.pyplot as plt
##S = np.array([SS() for i in range(200)])
##M = np.array([MC() for i in range(200)])
##
##print(np.mean(S))
##print(np.mean(M))
##
##print(np.std(S))
##print(np.std(M))
##
##plt.hist(S,label="S")
##
##plt.legend()
##plt.savefig("P3-1.jpg")
##plt.pause(0.01)
##plt.cla()
##plt.hist(M,label="M")
##plt.legend()
##plt.savefig("P3-2.jpg")
##plt.pause(0.01)
S = []
for n in range(5,20):
    S.append(SS(n=n,k=int(50000/n)))
S = np.array(S)

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)


def f(x):
    return 1 / (np.sqrt(x) + x)

# 积分区域划分
num_strata = 5000
strata_size = 1 / num_strata

# 每个子区域采样点数
num_samples_per_stratum = 10

# 计算每个子区域的采样点
samples = []
for i in range(num_strata):
    stratum_start = i * strata_size
    stratum_end = (i + 1) * strata_size
    stratum_samples = np.random.uniform(stratum_start, stratum_end, num_samples_per_stratum)
    samples.extend(stratum_samples)

# 计算每个采样点的函数值
values = f(samples)

# 计算积分近似值
integral_approx = np.mean(values)

print("Approximate integral value:", integral_approx)


Part 3 积分实战

CHOOSE

ERROR

N^(-1/2)

Best when alpha = 0.5

0.00167

0.3536

Num of Nodes is 8

Best when alpha = 0.6

0.04752

0.3015

Num of Nodes is 8

Best when alpha = 0.7

0.00167

0.3536

Num of Nodes is 8

Best when alpha = 0.8

0.00167

0.3536

Num of Nodes is 8


Part 6 高维积分

        Now,we will implement a MC method to find the volume of the N-dimensional sphere for the arbitrary dimension N and the sphere radius R.

        让我们估算一下一个25D的球体需要多少次实验才能得到精确的结果

1/(((1/25)**0.5)**25)=2.980232238769527e+17

        所以我们不可能从0-1开始取值,这样的运算量是我们不能接受的。

        利用C语言,我们创建了多个线程尽可能得将数值计算的极限推进到了13阶左右(计算用时在一分钟左右)

        同时我们希望使用Python语言进行编程,方便我们进行并行运算:并行运算的程序我们已在附件中给出了,遗憾的是,该方法仅能支持13阶左右的运行,远远达不到25阶的需求。(计算用时在一分钟左右)

        我们需要解决维度灾难问题。应该要从数学角度解决他。

                首先我们改用L1距离运算。稍微加快计算的速度

                其次,我们使用一个低差异序列(Sobol)序列生成更加均匀的随机数

运算结果

Dim

17

18

19

20

21

22

Theory

0.1409

0.0821

0.0466

0.0258

0.0139

0.0073

Calculate

0.1409

0.0821

0.0466

0.0258

0.0139

0.0073

23

24

25

26

27

0.0038

0.0019

0.0009

0.000466

0.000223

0.0038

0.0019

0.0009

0.000456

0.000198

import numpy as np
import scipy.special as spi
import matplotlib.pyplot as plt
np.random.seed(0)
import time


def prod(n):
    p = 1
    for i in range(1,n+1):
        p *= i
    return p

def f(n):
    if n%2==0:
        k = int(n/2)
        return np.pi**(k)/prod(k)
    elif n%2==1:
        k = int((n-1)/2)
        return np.pi**k*prod(k)*2**n/prod(n)

def main(Num=1e8,dim=4):
    assert(dim>=2),"dim should greater than 2!!!"
    Sum = 0
    #start = time.time()
    for i in range(int(Num)): 
        x = np.random.random(dim)
        p = sum(x**2)
        if p<=1:
            Sum += 1
    #end = time.time()
    #print("Used:",end-start)
    #print("Volume:",Sum/Num*(2**dim))
    #print("Theory:",f(dim))
    print(Sum)
    return Sum/Num*(2**dim),f(dim)

Dim = [20,21,22,23,24,25,26]
V = [0 for i in range(len(Dim))]
F = [0 for i in range(len(Dim))]


for i in range(len(Dim)):
    s = time.time()
    V[i],F[i] = main(dim=Dim[i])
    e = time.time()
    print(e-s)

    
plt.scatter(range(len(Dim)),V,c="red")
plt.scatter(range(len(Dim)),F,c="blue")
plt.plot(range(len(Dim)),V,c="red",label="volume")
plt.plot(range(len(Dim)),F,c="blue",label="Theory")
plt.legend()
plt.pause(0.01)


def main(Num=1e8,dim=4):
    Sum = 0
    for i in range(int(Num)): 
        x = np.random.random(dim)
        p = sum(x**2)
        if p<=1:
            Sum += 1
    print(Sum)
    return Sum/Num*(2**dim),f(dim)


main.py 

import datetime
import numpy as np

import multiprocessing as mp
 
    
def final_fun(name,param):
    dim = param
    Num = int(5*1e4)
    Sum = np.random.random((dim,Num))**2
    Sum = sum(Sum[:,:])
    Sum = len(np.where(Sum<=1)[0])
    
    return {name: Sum}
 
 
if __name__ == '__main__':

    dim = 20
    
    start_time = datetime.datetime.now()
 
    num_cores = int(mp.cpu_count())
    
    pool = mp.Pool(num_cores)
    param_dict = {'task1': dim,
                  'task2': dim,
                  'task3': dim,
                  'task4': dim,
                  'task5': dim,
                  'task6': dim,
                  'task7': dim,
                  'task8': dim,
                  'task9': dim,
                  'task10': dim,
                  'task11': dim,
                  'task12': dim,
                  'task13': dim,
                  'task14': dim,
                  'task15': dim,
                  'task16': dim}
    
    results = [pool.apply_async(final_fun, args=(name, param)) for name, param in param_dict.items()]
    
    results = [p.get() for p in results]
 
    end_time = datetime.datetime.now()
    use_time = (end_time - start_time).total_seconds()
 
    print("多进程计算 共消耗: " + "{:.2f}".format(use_time) + " 秒")
    print(results)

利用拉丁超立方体采样生成在高维更加均匀的随机数

拉丁超立方体采样的步骤如下:

        1.对于每个维度,将采样区间均匀地划分为相等的子区间。例如,如果要生成100个样本点,那么将采样区间[0, 1]划分为100个子区间,每个子区间的长度为1/100。

        2.在每个维度的每个子区间内,随机选择一个点作为采样点。可以使用均匀分布的随机数生成器来生成这些随机点。

        3.重复步骤2,直到在每个维度上都选择了一个采样点。

import numpy as np
np.random.seed(0)

def latin_hypercube_sampling(dimensions,num_samples):
    samples = np.zeros((num_samples,dimensions))

    intervals = np.linspace(0,1,num_samples+1)
    
    for i in range(dimensions):
        offsets = np.array([np.random.uniform(intervals[np.random.randint(0,num_samples+1)],intervals[np.random.randint(0,num_samples+1)]) for i in range(num_samples)])
        samples[:,i] = offsets
    
    return samples

if __name__ == '__main__':
    dimensions = 25
    num_samples = 1000
    
    # Perform Latin Hypercube Sampling
    samples = latin_hypercube_sampling(dimensions, num_samples)
    
    # Calculate mean and variance for each dimension
    means = np.mean(samples, axis=0)
    variances = np.var(samples, axis=0)
    
    # Print results
    print("Means:", means)
    print("Variances:", variances)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1027196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XUI - 一个简洁而优雅的Android原生UI框架

官网 GitHub - xuexiangjys/XUI: &#x1f48d;A simple and elegant Android native UI framework, free your hands! (一个简洁而优雅的Android原生UI框架&#xff0c;解放你的双手&#xff01;) XUI | &#x1f48d;A simple and elegant Android native UI framework, fre…

SAP 打note步骤

SAP 打note步骤 先确定需要实施的note 1.登录sap支持门户网站&#xff0c;查找note文件。https://support.sap.com/en/index.html 2.下载note文件到本地 3.事务代码SNOTE上传note文件 4.实施note,选中上传note&#xff0c;执行 5.往后一直确认 6.显示已实施成功 7.查看系…

计算机竞赛 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 人脸识别系统 该项目…

【数据结构】图的遍历:广度优先(BFS),深度优先(DFS)

目录 1、广度优先&#xff08;BFS&#xff09; 算法思想 广度优先生成树 知识树 代码实现 2、深度优先&#xff08;DFS&#xff09; 算法思想 深度优先生成树 知识树 代码实现 1、广度优先&#xff08;BFS&#xff09; 算法思想 图的广度优先遍历&#xff0…

【JDK 8-函数式编程】4.3 Consumer

一、Consumer 接口 二、使用 Stage 1: 创建方法&#xff0c;实现 Consumer 接口 Stage 2: 调用方法 Stage 3: 执行结果 三、List 的 foreach 执行结果 一、Consumer 接口 消费型接口 : 将T作为输入&#xff0c;无返回值 调用方法 : void accept(T t); 用途 : 因为没有出…

代码随想录算法训练营第23期day1|704. 二分查找、27. 移除元素

目录 一、&#xff08;leetcode 704&#xff09;二分查找 1&#xff09;左闭右开 2&#xff09;左闭右闭 二、&#xff08;leetcode 27&#xff09;移除元素 1&#xff09;暴力解法 2&#xff09;双指针法 快慢指针法 双向指针 数组是存放在连续内存空间上的相同类型数…

HTML5编写旅游网页

网页样例&#xff1a;&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…

【Java 基础篇】Java线程同步:Lock接口详解

在多线程编程中&#xff0c;线程同步是一个重要的话题。为了确保多个线程可以正确地协同工作&#xff0c;Java提供了多种线程同步机制。其中&#xff0c;Lock接口是一种强大而灵活的线程同步机制&#xff0c;它提供了比传统的synchronized关键字更多的控制和功能。本文将详细介…

mac安装chromedriver驱动详细步骤

1.查看浏览器版本 2.下载驱动 3.安装驱动 4.MacOS无法打开“chromedriver”&#xff0c;因为无法验证开发者 1.查看浏览器版本 在这里插入图片描述 2.下载驱动 下载驱动地址&#xff1a;链接: http://chromedriver.storage.googleapis.com/index.html. 下载和浏览器版本一致的…

图解直接映射(Direct mapped)、全相联(Fully-associative)和组相联(Set-associative)cache缓存基本原理

图解直接映射&#xff08;Direct mapped&#xff09;、全相联&#xff08;Fully-associative&#xff09;和组相联&#xff08;Set-associative&#xff09;cache 一&#xff0c;直接映射缓存&#xff08;Direct mapped caches&#xff09;1.1 直接映射示例1.2 直接映射原理1.3…

人类认知的贝叶斯与机器的贝叶斯

贝叶斯原理是一种基于概率的分析方法&#xff0c;可以用来估计一个事件发生的概率。在人类认知和机器学习领域中&#xff0c;都有对应的贝叶斯原理。 人类认知的贝叶斯原理&#xff1a; 在人类认知研究中&#xff0c;贝叶斯原理被认为是一种重要的思维方式。人类的认知过程通常…

算法、数据结构、计算机系统、数据库MYSQL、概率论、数学实验MATLAB、数学建模、马原、英语、杂项、QT项目

算法 冒号表达式 &#xff08;condition&#xff09;&#xff1f;x&#xff1a;y 可以三个条件 以此类推 &#xff08;condition1&#xff09;&#xff1f;x&#xff1a;&#xff08;condition2&#xff09;&#xff1f;y&#xff1a;z 判断三角形最简单的办法 bool canFormTr…

使用 K 均值聚类进行颜色分割

介绍 颜色分割是计算机视觉中使用的一种技术,用于根据颜色识别和区分图像中的不同对象或区域。聚类算法可以自动将相似的颜色分组在一起,而不需要为每种颜色指定阈值。当处理具有大范围颜色的图像时,或者当事先不知道确切的阈值时,这非常有用。 在本教程中,我们将探讨如何…

修炼离线:(三)sqoop插入hbase 报错权限问题

一&#xff1a;报错现象。 二&#xff1a;解决方式。 方法一&#xff1a;修改文件所有者。 切换hadoop用户&#xff1a;export HADOOP_USER_NAMEhdfs hadoop fs -chown -R root:root /方法二&#xff1a;修改权限 切换hadoop用户&#xff1a;export HADOOP_USER_NAMEhdfs ha…

现今主流物联网无线通信技术分类详解

无线技术正在迅速发展&#xff0c;并在人们的生活中发挥越来越大的作用。 而随着无线应用的增长&#xff0c;各种技术和设备也会越来越多&#xff0c;也越来越依赖于无线通信技术。 本文盘点下物联网中无线通信主要的技术。 一、无线通信技术的几大主流分类 1.美国通信委员会…

Fork() 函数:“父” 与 “子” 进程的交互(进程的创建)

阅读导航 前言一、fork函数初识1. 基本概念2. fork函数返回值 二、fork函数的写时拷贝三、总结温馨提示 前言 前面我们讲了C语言的基础知识&#xff0c;也了解了一些数据结构&#xff0c;并且讲了有关C的一些知识&#xff0c;也学习了一些Linux的基本操作&#xff0c;也了解并…

CDN内容分发系统

CDN 分发系统的架构。CDN 系统的缓存&#xff0c;也是一层一层的&#xff0c;能不访问后端真正的源&#xff0c;就不打扰它。 在没有 CDN 的情况下&#xff0c;用户向浏览器输入 www.web.com 这个域名&#xff0c;客户端访问本地 DNS 服务器的时候&#xff0c;如果本地 DNS 服务…

单片机第三季-第三课:STM32开发板原理图、配置、浮点运算单元

目录 1&#xff0c;开发板原理图 2&#xff0c;浮点运算单元&#xff08;FPU&#xff09; 1&#xff0c;开发板原理图 课程视频比较早&#xff0c;介绍了三款开发板。观看视频时用的开发板说和51单片机共板的STM32核心板&#xff0c;将51单片机从底座拆下来后&#xff0c;安…

HiEV独家 | 接棒余承东,华为光产品线总裁靳玉志出任车BU CEO

作者 | 德新 编辑 | 王博 HiEV从多个信息源获悉&#xff0c;华为光产品线总裁靳玉志已于近期接任智能汽车解决方案BU CEO一职&#xff0c;而余承东担任智能汽车解决方案BU&#xff08;以下简称「车BU」&#xff09;董事长一职。 华为光产品线又称华为光传输与接入产品线&#…

基于Uniapp+SpringBoot+Vue的电影交流平台小程序设计与实现(源码+lw+部署文档+讲解等)

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…