• 蒙特卡洛方法的简单应用


    • 蒙特卡洛方法的简单应用

    圆周率估算

    eastimate pi
    python version 3.11
    RNG:np.random.random

    1. import os
    2. figure_save_path = "file_fig"
    3. import warnings
    4. warnings.filterwarnings("error")
    5. import numpy as np
    6. np.random.seed(0)
    7. import matplotlib.pyplot as plt
    8. from PIL import Image
    9. def main(times=100):
    10. print("RNG:", "Python numpy.random.random")
    11. print("开始估算")
    12. Nlist = [1000000*i for i in range(1, times)]
    13. Pilist = []
    14. Slist = []
    15. gif_frames = []
    16. for i in range(1, times):
    17. N = Nlist[i-1]
    18. random_points = np.random.random((2, N))
    19. radius = sum(random_points[:]**2)
    20. count = np.sum(radius<=1)
    21. ave = count/N
    22. S2 = ((N-count)*ave**2+count*(1-ave)**2)/(N-1)
    23. S = S2**0.5
    24. Pilist.append(4*ave)
    25. Slist.append(4*S/N**0.5)
    26. plt.xlabel("test_times")
    27. plt.ylabel("estimate_pi_value", rotation=90)
    28. plt.title("Estimate Pi")
    29. plt.errorbar(Nlist[:i], Pilist[:i], Slist[:i], label="estimate pi", c="green")
    30. plt.axhline(np.pi,label="exact pi", c="red")
    31. plt.legend()
    32. if not os.path.exists(figure_save_path):
    33. os.makedirs(figure_save_path)
    34. else:
    35. pass
    36. plt.savefig(os.path.join(figure_save_path, str(i) + ".jpg"))
    37. plt.cla()
    38. img = Image.open(os.path.join(figure_save_path, str(i) + ".jpg"))
    39. gif_frames.append(img)
    40. print("估算完成")
    41. print("开始绘制动画")
    42. gif_frames[0].save("estimate-pi.gif",
    43. save_all=True, append_images=gif_frames[1:], duration=200, loop=0)
    44. print("动画绘制完成")
    45. main()
    46. input("press any key to exit")
    • 动画

    二维积分估算

    • 2dintegral
    • RNG:numpy.random.random
    • Python version:3.11
    • 允许积分类型 \int\int f(x,y)dxdy

        

    • 若实现手动输入方程功能会增加程序解析负担,大约是十倍左右,故不予实现
    • 若需要实现,可以仿照如下例子:
    1. def main(X_start=0, X_end=1, Y_start=0, Y_end=1):
    2.     print("RNG:numpy.random.random")
    3.     print("")
    4.     funstr = input("输入方程")
    5.     #funstr = "x**2*y**2"
    6.     f = lambda x,y: eval(funstr)
    7.     #f = lambda x,y:x**2*y**2
    8.     print("运算开始")
    9.     
    10.     N = 10000
    11.     
    12.     start = time.time()
    13.     random_xpoints = np.random.uniform(X_start, X_end, N)
    14.     random_ypoints = np.random.uniform(Y_start, Y_end, N)
    15.     X = np.arange(X_start, X_end, 100)
    16.     Y = np.arange(Y_start, Y_end, 100)
    17.     guess = np.array(list(map(f, random_xpoints, random_ypoints)))
    18.     ave = sum(guess)/N
    19.     I = ave*(X_end-X_start)*(Y_end-Y_start)
    20.     S2 = sum((guess-ave)**2)/(N-1)
    21.     S  = S2**0.5
    22.     end = time.time()
    23.     
    24.     print(I, "\pm", S/N**0.5)
    25.     print("运算结束,用时:", round(end-start, 4))

    拒绝抽样方法

    1. import os
    2. figure_save_path = "file_fig"
    3. import warnings
    4. warnings.filterwarnings("error")
    5. import numpy as np
    6. np.random.seed(0)
    7. import matplotlib.pyplot as plt
    8. from PIL import Image
    9. from copy import deepcopy
    10. plt.rcParams['font.sans-serif'] = ['FangSong']
    11. plt.rcParams['axes.unicode_minus'] = False
    12. ######
    13. #待抽样分布x~f(x)
    14. #已有分布g(x)
    15. #建议分布c*g(x)
    16. #在概率空间有c*g(x)恒大于f(x)
    17. #step 1 按f(x)抽样 得x,x_i~f(x) x.size
    18. #step 2 生成u,u_i~U[0, max(c*g(x))] u.size = x.size
    19. #step 3 从x中选取满足u_i<f(x_i)的样本
    20. ######
    21. f1 = lambda x:0.3/np.sqrt(np.pi*2)*np.exp(-(x+2)**2/2) +\
    22. 0.7/np.sqrt(np.pi*2)*np.exp(-(x-4)**2/2)
    23. x_start = -10
    24. x_end = 10
    25. def main(f1=f1, x_start=x_start, x_end=x_end, N = int(1e+7), maxiter = 1000):
    26. #已有分布为 numpy.random.random 导出的均匀分布
    27. num_wanted = deepcopy(N)
    28. result = np.zeros(num_wanted)
    29. has_get_num = 0
    30. itertimes = 0
    31. random_num = np.zeros(N)
    32. x = np.arange(x_start, x_end, 0.01)
    33. if N >= int(1e4):
    34. N = int(num_wanted /10)
    35. else:
    36. pass
    37. while has_get_num < num_wanted:
    38. itertimes += 1
    39. if itertimes >= maxiter:
    40. print("无法生成足够多的随机数")
    41. break
    42. else:
    43. pass
    44. #拒绝方法:cg(x)<=f(x)
    45. sample_try = np.random.random(N)
    46. sample_try = (x_end - x_start) * sample_try + x_start
    47. sample_test= f1(sample_try)
    48. c = 1 + max(f1(x))
    49. sample_test *= c
    50. sample_help = np.random.random(N) * (max(sample_test)-0) + 0
    51. sample = sample_try[sample_help<sample_test]
    52. if has_get_num + sample.size > num_wanted:
    53. result[has_get_num:num_wanted-1] = sample[:num_wanted-has_get_num-1]
    54. else:
    55. result[has_get_num:has_get_num+sample.size] = sample
    56. has_get_num += sample.size
    57. plt.title("随机数生成分布")
    58. plt.xlabel("随机数")
    59. plt.ylabel("比例")
    60. plt.plot(x, f1(x), color='red', label="待抽样分布", linewidth=2)
    61. plt.hist(result, bins=200, label="随机数柱状分布图", color='green', density=True)
    62. plt.legend(prop={'size': 10})
    63. plt.pause(0.01)
    64. if not os.path.exists(figure_save_path):
    65. os.makedirs(figure_save_path)
    66. else:
    67. pass
    68. plt.savefig(os.path.join(figure_save_path, "随机数生成分布" + ".jpg"))
    69. return result
    70. c = main()

    多维随机向量的抽样

    • 拒绝抽样方法
    • 条件密度抽样方法

     

  • 相关阅读:
    入门ROS其实也没有那么难!
    startActivityForResult废弃了,用Activity Result API吧
    Feign 实现 GET 方法传递 POJO
    手机号码格式校验:@PhoneQuery(作为查询参数)(自定义参数校验注解)
    数据库索引这么做才有谱
    利用transform和border 创造简易图标,以适应uniapp中多字体大小情况下的符号问题
    QT---day2---9.18
    独家下载|《阿里云MaxCompute百问百答》 解锁SaaS模式云数据仓库尽在本电子手册!
    asp核酸检测预登记系统源码
    y47.第三章 Kubernetes从入门到精通 -- ceph 在k8s中的使用案例(二十)
  • 原文地址:https://blog.csdn.net/Chandler_river/article/details/133768776