冠层图形和随机化误差

时间:2015-06-09 18:10:54

标签: python

import math
import pylab as plt
import numpy
from numpy import sqrt
from scipy.integrate import quad
import random

numpy.seterr(divide='ignore', invalid='ignore')

#this integrates sqrt(1-x^2) from 0 to 1 and stores the value in q1area
def integrand (x):
return sqrt(1-x**2)
q1area, err = quad(integrand,0,1)

print "This program estimates the convergence of Pi to a ratio of one."

#code enters a while loop that runs until the user decides to exit the code (choice 4)
while True:
    print "Please choose from one of the five following options:"
    print " 1. 10^1\n 2. 10^2\n 3. 10^3\n 4. Exit"
    choice = int(raw_input())
    options = {1,2,3,4}

if choice == 1:
    #sets the x and y bounds on the graph
    plt.xlim([0,12])
    plt.ylim([-5,5])

    #sets the graph for the program to store random points on - sqrt(1-x^2)
    x = numpy.linspace(0,12,500)
    y = numpy.sqrt(1-x**2)
    #the program says that x and y need to be of the same dimension
    #if z doesn't have the x*0 term. That term seems to fix the error
    z = 1+x*0

    xcord = []
    ycord = []
    under = []
    above = []
    pratiolist = []
    yvalues = []
    xvalues = range(1,11)

    #appends a random point on the graph
    for i in range(10):
        xcord.append(random.random())
        ycord.append(random.random())

    #checks to see if the point is under or above the curve then assigns it to 
    #the corresponding list
    for j in ycord:
        if (j <= q1area):
            under.append(1)

        else:
            above.append(1)

        #defines two variables value as the length of a list
        punder = len(under)
        pabove = len(above)

        #checks for division by zero, adds one if true
        if pabove == 0:
            pabove = pabove + 1

        #calculates pratio as points above and below, creates list, appends values
        pratio = punder / float(pabove)
        pratiolist.append(pratio)

    #runs through pratiolist and calculates ratio to pi for each point
    for k in pratiolist:
        rtpi = k / float(math.pi)
        yvalues.append(rtpi)

    #displays graph
    plt.scatter(xvalues,yvalues,c='b')
    plt.plot(x,z,'g')
    plt.show()

if choice == 2:
    plt.xlim([0,120])
    plt.ylim([-5,5])

    x = numpy.linspace(0,120,500)
    y = numpy.sqrt(1-x**2)
    z = 1+x*0

    xcord = []
    ycord = []
    under = []
    above = []
    pratiolist = []
    yvalues = []
    xvalues = range(1,101)

    for i in range(100):
        xcord.append(random.random())
        ycord.append(random.random())

    for j in ycord:
        if (j <= q1area):
            under.append(1)

        else:
            above.append(1)

        punder = len(under)
        pabove = len(above)

        if pabove == 0:
            pabove = pabove + 1

        pratio = punder / float(pabove)
        pratiolist.append(pratio)

    for k in pratiolist:
        rtpi = k / float(math.pi)
        yvalues.append(rtpi)

    plt.scatter(xvalues,yvalues,c='b')
    plt.plot(x,z,'g')
    plt.show()

if choice == 3:
    plt.xlim([0,1100])
    plt.ylim([-5,5])

    x = numpy.linspace(0,1100,500)
    y = numpy.sqrt(1-x**2)
    z = 1+x*0

    xcord = []
    ycord = []
    under = []
    above = []
    pratiolist = []
    yvalues = []
    xvalues = range(1,1001)

    for i in range(1000):
        xcord.append(random.random())
        ycord.append(random.random())

    for j in ycord:
        if (j <= q1area):
            under.append(1)

        else:
            above.append(1)

        punder = len(under)
        pabove = len(above)

        if pabove == 0:
            pabove = pabove + 1

        pratio = punder / float(pabove)
        pratiolist.append(pratio)

    for k in pratiolist:
        rtpi = k / float(math.pi)
        yvalues.append(rtpi)

    plt.scatter(xvalues,yvalues,c='b')
    plt.plot(x,z,'g')
    plt.show()

if choice == 4:
    break

while choice not in options:
    print "Not a valid choice!\n"

部分空白区域已关闭,我不确定如何标记多行。无论如何,这段代码需要10,100或1000个点,并在y = 0和1之间的sqrt(1-x ^ 2)图表上随机断言,x = 0和1。

graph of sqrt(1-x^2)

然后取这些点的比率并将其与Pi的实际值进行比较,得到一个等于1的收敛图(估计的点数越多越好)。

pi ratio

我有两个问题。第一个可能非常明显......第二张图上的那些点并不像我想的那样随意。它们似乎以线性方式上升并重新开始。

第二个问题是我想让这段代码循环,让用户一遍又一遍地选择三个选项中的一个,直到他们选择退出。每次,这应该清除图表,并使一个新的随机化一切。这不是我得到的行为。有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

对于问题2:原因是您计算曲线上方点数与点数之比的方式。随着pabove随时间递增,比率逐步改变。步数越多,这种情况就会变得越来越少 问题1:查看代码如何处理无限输入循环

一些评论(后面的代码中有很多很多其他提示):
- 你似乎省略了绘制随机点的命令(图1)。我在代码中留下了数组定义,否则这些定义将是未使用/多余的 - 您将y值与积分q1area进行比较。如果您只查看尺寸(长度与面积),这可能是不对的。我已将比较替换为它应该是什么 - 将点位置(使用x和y)与曲线上的点进行比较。曲线q1area以下区域的度量实际上根本没有使用。

这是我的代码主张,我无法运行或测试,因为我没有安装所有模块:

import math
import pylab as plt
import numpy
from numpy import sqrt
from scipy.integrate import quad
from random import random

### numpy.seterr(divide='ignore', invalid='ignore')

# function to integrate
def integrand (x):
    return sqrt(1-x**2)

# calculate integral with error estimate
q1area, error_estimate = quad(integrand, 0, 1)

print "This program estimates the convergence of Pi to a ratio of one."
pi = math.pi

while True:
    choice = 0
    options = [1, 2, 3, 4]
    while choice not in options:
        print "Please choose from one of the four following options:"
        print " 1. 10^1 steps\n 2. 10^2 steps\n 3. 10^3 steps\n 4. Exit"
        choice = int(raw_input())
    if choice == 4:
        break

    n = 10**choice # number of random samples

    # set the x and y bounds on the graph
    plt.xlim([0, 1.2*n])
    plt.ylim([-5, 5])

    # set the graph for the program to store random points on - sqrt(1-x^2)
    x = numpy.linspace(0, 1.2*n, 500)
    y = numpy.sqrt(1 - x**2)
    # x and z need to be of the same dimension
    # if z doesn't have the x*0 term. That term seems to fix the error
    z = 1 + x*0 # constant 1 over the range of x values

    xcoord = []
    ycoord = []
    pratiolist = []
    xvalues = range(1, n+1)
    yvalues = []

    # append n random points on the graph
    for i in range(n):
        xcoord.append(random())
        ycoord.append(random())

        # count if the point at (xcoord[i],ycoord[i]) is under or above the curve
        if ycoord[i] <= integrand(xcoord[i])::
            punder += 1
        else:
            pabove += 1

        # calculates pratio as points above and below, creates list, appends values
        if pabove > 0:
           pratiolist.append(punder / float(pabove))
        else:
           pratiolist.append(punder)

    # run through pratiolist and calculates ratio to pi for each point
    for k in pratiolist:
        rtpi = k / float(pi)
        yvalues.append(rtpi)

    # display graph
    plt.scatter(xvalues, yvalues, c='b')
    plt.plot(x, z, 'g')
    plt.show()

您将看到您不必使用与开始时一样多的阵列,例如计数。
主要的比较是使用integrand()函数,这样如果更改要集成的函数,就不必更改代码。