Menu

[r6218]: / trunk / py4science / examples / montecarlo_pi.py  Maximize  Restore  History

Download this file

134 lines (102 with data), 2.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
"""Simple generation of pi via MonteCarlo integration.
To do:
- plot convergence
- plot timing comparisons
- implement using numpy
- binned numpy (to avoid creating a very large list,
"""
import math
import random
import numpy as N
from scipy import weave
from scipy.weave import inline,converters
def v1(n = 100000):
"""Approximate pi via monte carlo integration"""
rand = random.random
sqrt = math.sqrt
sm = 0.0
for i in xrange(n):
sm += sqrt(1.0-rand()**2)
return 4.0*sm/n
def v2(n = 100000):
"""Implement v1 above using weave for the C call"""
support = "#include <stdlib.h>"
code = """
double sm;
float rnd;
srand(1); // seed random number generator
sm = 0.0;
for(int i=0;i<n;++i) {
rnd = rand()/(RAND_MAX+1.0);
sm += sqrt(1.0-rnd*rnd);
}
return_val = 4.0*sm/n;"""
return weave.inline(code,('n'),support_code=support)
def matprint(mat):
"""Simple matrix printer in C++ using weave and blitz.
"""
nrow,ncol = mat.shape
code = \
"""
for(int i=0;i<nrow;i++) {
for(int j=0;j<ncol;j++) {
std::cout << mat(i,j) << " ";
}
// Line end after each row
std::cout << std::endl;
}
"""
# This function doesn't return anything
inline(code,['mat','nrow','ncol'],
# The type_converters argument allows us to access an array's
# elements using arr(i,j) syntax inside the C++ code
type_converters = converters.blitz)
# Returning a scalar quantity computed from an array.
def trace(mat):
"""Return the trace of a matrix.
"""
nrow,ncol = mat.shape
code = \
"""
double tr=0.0;
for(int i=0;i<nrow;++i)
tr += mat(i,i);
return_val = tr;
"""
return inline(code,['mat','nrow','ncol'],
type_converters = converters.blitz)
# In-place operations on arrays in general work without any problems
def in_place_mult(num,mat):
"""In-place multiplication of a matrix by a scalar.
"""
nrow,ncol = mat.shape
code = \
"""
for(int i=0;i<nrow;++i)
for(int j=0;j<ncol;++j)
mat(i,j) *= num;
"""
inline(code,['num','mat','nrow','ncol'],
type_converters = converters.blitz)
if __name__ == '__main__':
# Monte Carlo Pi:
print 'pi is:', math.pi
print 'pi - python:',v1()
print 'pi - weave :',v2()
# make a simple 10x10 array
a = N.arange(100)
a.shape = 10,10
# Print it using our printer
print "array a:"
matprint(a)
# Print its trace
print 'A trace:',a.trace()
# And computed via our C++ code:
print trace(a)
# Multiply it in-place and compare:
b = a.copy()
in_place_mult(10,a) # with our C++ code
b *= 10 # Using the standard python operations
print 'First row of a:',a[0]
print 'First row of b:',b[0]
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.