def f(x) x/((x+1.0)*(x+2.0)) end def trapezoid(xs,xe,n) deltax = (xe-xs)*1.0/n sum = (f(xs)+f(xe))/2.0 for i in 1..(n-1) sum = sum + f(xs+i*deltax) end deltax * sum end
trapezoid.rb の f を定義しなおし、
def pi(n) 4.0 * trapezoid(....) end
ヒント
def f(x) # に対応する式を書く end def simpson(xs,xe,n) deltax = (xe-xs)*0.5/n sum = f(xs)+f(xe)+4*f(xs+deltax) for i in 1..(n-1) sum = sum + ... * f(xs+2*i*deltax) + ..... # 穴埋め end deltax * sum / 3.0 end以下を確かめる
f(0.0) -> 1.0 f(0.5) -> 0.8 f(1.0) -> 0.5 4.0*simpson(0.0,1.0,100) -> 3.14159265….
以下を確かめる
f(0.0) -> 1.0 f(0.5) -> 0.866025... f(1.0) -> 0.0 4.0 * simpson(0.0,1.0,10) 4.0 * simpson(0.0,1.0,100) 4.0 * simpson(0.0,1.0,1000) 4.0 * simpson(0.0,1.0,10000) 4.0 * simpson(0.0,1.0,100000)
def montecarlo(n) m=0 for i in 1..n x=rand() # random number in [0,1) y=rand() if x*x + y*y < 1.0 m = m + 1 end end m*1.0/n end
def mcplot(n) a = make2d(500,500) for i in 1..n x= rand() # random number in [0,1) y= rand() if x*x + y*y < 1.0 a[y*500][x*500] = 1.0 else a[y*500][x*500] = 0.5 end end a end
0 01111111 10000000000000000000000(単精度表現)
s e1e2...e8 f1f2...f23と表現される数は,
(-1)s × (1.f1f2...f23)(2) × 2 (e1e2...e8)(2)-127である(例外として,指数部と仮数部がすべて0の実数は0になる).Ruby言語では2進数の整数は先頭に「0b」をつけて表現できるので,
(-1)**(s) * (0b1f1f2...f23 * 2**(-23)) * 2**(0be1e2...e8 - 127)を計算すれば良い.今の例では,
(-1)**(0) * (0b110000000000000000000000 * 2**(-23)) * 2**(0b01111111 - 127)となる.
0 10000000 10000000000000000000000(単精度表現)
0 01111110 00000000000000000000000(単精度表現)
0 00000000 00000000000000000000000(単精度表現)
1.0/3.0 => 0.333333333333333だが,小数点以下8桁を求めるために,2**8=256倍してみる.
(1.0/3.0)*256 => 85.3333333333333整数を2進数に直すには,「.to_s(2)」をつける.
85.to_s(2) => "XXXXXXX"したがって,
(1.0/3.0) = 0.0XXXXXXX....となる.
0.1 * 3 == 0.3
0.1 * 3 - 0.3
2 ** -54
include(Math) def abs (x) if x >=0 x else -x end end def f(x) log(x) end def cancellations(x,h_digits) errors=Array.new(h_digits+1) for i in 0..h_digits h = 0.1**i df=(f(x+h)-f(x))/h errors[i] = abs(df-1.0/x) end errors end
cancellations(2.0,15)
# simulate 32 bit floating point representaiton def coerce32(f) [f].pack("f").unpack("f")[0] end def sum(digits) n=10**digits sum = 0.0 d = coerce32(1.0 / n) for i in 1..n sum = coerce32(sum + d) end sum end
sum(6) sum(7) sum(8)
def gj(a) # Gauss-Jordan method without pivoting row = a.length() col = a[0].length() for k in 0..(col-2) akk = a[k][k] for i in 0..(col-1) # normalize row k a[k][i]=a[k][i]*1.0/akk end for i in 0..(row-1) # eliminate column k if i != k # of all rows but k aik = a[i][k] for j in k..(col-1) a[i][j] = a[i][j] - aik * a[k][j] end end end end a end
a=[[1,1,-1,2], [3,5,-7,0], [2,-3,1,5]] gj(a)
def abs (x) if x >=0 x else -x end end #a[i][k]の絶対値が最大となるi>=kを探す def maxrow(a,k) max_i=k for i in (k+1)..(a.length()-1) if abs(a[max_i][k]) < abs(a[i][k]) # 穴埋め end end max_i end def swap(a,i,j) tmp=a[i] a[i]=a[j] a[j]=tmp end def gjp(a) # Gauss-Jordan method WITH pivoting row = a.length() col = a[0].length() for k in 0..(col-2) max=maxrow(a,k) # find absolute-maximal coeff. swap(a,k,max) # swap rows akk = a[k][k] for i in 0..(col-1) # normalize row k a[k][i]=a[k][i]*1.0/akk end for i in 0..(row-1) # eliminate column k if i != k # of all rows but k aik = a[i][k] for j in k..(col-1) a[i][j] = a[i][j] - aik * a[k][j] end end end end a end
b=[[1,-50,-3,-90], [-85,2,-25,-6], [79,5,30,-1]] gj(b)一度解を求めると b が書き変わってしまうので,もう一度解く前にbを設定し直す必要がある.
b=[[1,-50,-3,-90], [-85,2,-25,-6], [79,5,30,-1]]
maxrow(b,0) => 1 maxrow(b,1) => 2
gjp(b)