計算物理 2011atlas.shinshu-u.ac.jp/class/kclass/計算物理11.pdf · 2011-07-27 ·...
TRANSCRIPT
計算物理 2011
竹下徹
物理学で計算機理解する C言語を使って計算させる
11
計算機内部の表現 ;8bit
計算機なかでは数字も文字もbitの集合
2進法の一桁を表す:ビット bit10
2進法の8桁を表す:バイト byte
2の8乗=256通りの組み合わせ=256種の文字
ASCII: アスキー : American Standard Code for
Information Interchange
0011 0000 : "0"
0011 0001 : "1"
0011 1001 : "9"
.....
0100 0001 : "A" 0110 0001 : "a"
0100 0010 : "B" 0110 0010 : "b"
...
0101 1010 : "Z" 0111 0010 : "z"
22
計算機内部の表現 ;UNICODE
日本語:16ビット:2バイト;全角2の16乗=65536通りの組み合わせ:ASCIIを含む
ISO : International Organization for Standardization . 国際標準化機構. ISO-10646
0000 0000 0011 0000 : "0"
0000 0000 0011 0001 : "1"
0000 0000 0011 1001 : "9"
.....
0000 0000 0100 0001 : "A"
0000 0000 0110 0001 : "a"
0110 0001 0001 1011 : "愛" 611B
ASCII
33
計算機内部の表現 ;数字 :IEEE754
32ビット:4バイト2の32乗通りの組み合わせ
整数
0000 0000 0000 0000 0000 0000 0000 0000 : 0
0000 0000 0000 0000 0000 0000 0000 0001 : 1
0000 0000 0000 0000 0000 0000 0000 1001 : 9
.....
1111 1111 1111 1111 1111 1111 1111 1111 : -1
実数
1bit 8bit 23bit
e as
実数 X =(-1) [0.a] x 2s
(2) e -127(10)
(10)
実数 6.0 =0 10000001 10000000000000000000000(10)
実数 -0.375 =1 01111101 10000000000000000000000(10)
44
C事初め•作法がある
•プログラムは上から下へ一行づつ実行
• #include <stdio.h> 最低限
•main { で始まり、}で終わる
•変数は整数型か、実数型か定義する
•画面への出力は printf(“%?” 変数名);? = d整数、f実数
•各実行は; セミコロンで終わる
#include <stdio.h>main { int i,j,k;float a,b,c;...printf(“ %d %d %f \n“,i,j,a);}
55
Cの計算•左辺Aへ右辺Bの計算結果を代入 A=B 計算 記号 例加算 + c=a+b減算 - c=a-b乗算 * c=a*b除算 / c=a/bあまり % c=a%b c=a-(a/b)*b [int a,b,c]1加算 ++ k++ k=k+11減算 ーー k-- k=k-1和の代入 += k+=5 k=k+5差の代入 -= k-=5 k=k-5積の代入 *= a*=5 a=a*5商の代入 /= a/=5 a=a/5
あまりの代入 %= a%=5 a=a%5
μ
66
for 文•繰り返し
•整数 k ,実数 x,y
for ( k=1; k<10;k++) { x=k/10.0; y=sin(x); printf(“ %d %f %f \n“, k,x,y);}
結果k=1x=1/10.0=0.1y=sin(0.1)k=2x=2/10.0=0.2y=sin(0.2)k=3x=3/10.0=0.3y=sin(0.3)...../a.out > aplot.dat
sin(x) は数学関数 #include <math.h> が必要
> redirection7
7
カオスのシミュレーション•実数変数xはある集団の個体数(1で規格化されている)
• 実数変数aは子供の増え方を表す増倍率である
• この系をfor文で計算させるととても奇妙な振る舞いをする
for ( k=1; k<10;k++) { x=a*x*(1.0-x); printf(“ %d %f \n“, k,x);}
x
k横軸世代
aが大きい場合飢餓と繁殖を繰り返す
88
世代と個体数x
a
x
• x=a*x*(1-x)の系は面白い
• a が1より小さいと滅亡 x->0
• aが1~?の間では一定値に収束する
• aが?~3.5付近以上になるとカオスである(全ページ)
• さらに大きくなるとxが1を超える
99
for 文その2•整数 k,s
• 和をとる:初期化s=0
• s=s+k はs+=k
•と書いてもよい
int k,s;s=0;for( k=1;k<5,k++){ s=s+k; printf(“ %d %d \n“,k,s) ;}
1010
和の計算float x,s;s=0.0for (k=1;k<10;k++){ x=1.0/k; s=s+x; printf(“%d %f %f ”,k,x,s);}
s=k1
k=1
10
!k-> で発散(log)
€
1+122
+132
+142...= π 2
6= ς(2)€
∞
次を示せ;11
11
無限級数和
が収束するsの条件を見つけよ
€
Z(s) =1ksk=1
∞
∑€
Z(s) =1ksk=1
∞
∑
€
Z(2) =16⎛
⎝ ⎜ ⎞
⎠ ⎟ π 2,Z(4) =
190⎛
⎝ ⎜
⎞
⎠ ⎟ π 4
s=2,4を計算で示せ
を計算で示せ
€
1− 13
+15−17
+ ....= π4
マクローリン 展開を示せ
€
ex =1+x1!
+x 2
2!+x 3
3!+ ....
複数のxについて等号を計算して確かめる
問1:問2:
問3:問4:
1212
階乗計算•n! 計算
•破綻
•倍精度計算
• long k,s;
• %d を%ld
int k,s;s=1;for( k=1;k<19,k++){ s=s*k; printf(“ %d %d\n “,k,s) ;}
1313
フーリエ級数
€
f (x) =4π
sin{(2k −1)x}2k −1k=1
∞
∑
x
f(x)任意の周期関数は三角関数の和で表される
plot [-3.14159:3.14159][] 4/3.14159*(sin(x)/1),4/3.14159*(sin(x)+sin(3*x)/3),4/3.14159*(sin(x)/1+sin(3*x)/3+sin(5*x)/5)
矩形関数
€
f (x) =1+ 2cos(kx)k= 0
∞
∑問題: impulse14
14
•プログラム例
€
f (x) =1+ 2cos(kx)k= 0
∞
∑for (j=1;j<jm,j++){x=-5.0 + j /10.0; for(k=0;k<km;k++){ f=f+2*cos(k*x); }}
kmax=25 kmax=50 kmax=200どんな関数でしょう?
1515
キーボードから入力•数値xを読みこむ
• scanf()が入力関数float x;
printf(" input a value : "); scanf("%f",&x);
1616
(数値)積分•積分;面積計算
•長方形近似
s
y=f(x)
x
s=f(x)*dx
f(x)
dx
€
S = f (x)dxa
b∫
dx=(b-a)/n;for(k=0;k<n;k++){ x=a+dx*k; s=s+f(x)*dx;}
s s ss s s
a b台形近似
s=s+(f(x)+f(x-dx))*dx/2;
1717
関数文•function();
• main 文の外に関数を置くこともできる
•複雑な関数なら間違いがない
•変数のつながりに注意
void f(); main(){...........}f(x);{f=sin(x)*exp(-x);}
1818
課題•Plank分布:黒体からの光(波長m)の分布
•黒体放射強度分布=プランク分布: B(m)
• B (m)を波長の全域で積分すると温度Tのエネルギーを計算できる
•この値は温度Tの4乗に比例する、これを示せ:シュテファン=ボルツマンの法則
€
B(λ) =2hc 2
λ51
ehc /λkT −1 Tは温度
h=c=k=1の単位で計算せよ1919
Plank 分布の積分と微分case : h=k=c=1
T
積分結果
T4線
Stefan-Boltzmann則 Wien変位則
T
T-1線
微分結果gnuplot set logscale
2020
if 文•もし なんとか なら
• if (なんとか)
• 式
• else <<< そうでないなら
•式
•右のプログラムは何をしているか?
scanf(“%f”,&x);scanf(“%f”,&y);if(x<y) {z=x-y;}else{z=y-x;}printf(“%f\n”,z);
2121
if ()a>b if(a>b)
a>=b if(a>=b)
a<=b if(a<=b)
a=b if(a==b)
not equal if(a!=b)
(式1) AND ( 式2) if( (式1) &&(式2) )
(式1) OR ( 式2) if( (式1) || (式2) )
要注意:実数が==になることはまずない
整数整数
2222
数値微分•関数を微分
•有限hで近似
•極大値を探す
•微分係数gが正の間印刷
•印刷が止まると極大値
• f=x3-x+1 の極大を計算
for(k=0;k<?; k++) {x=a+h*k;g=(f(x+h)-f(x))/h;if(g>0) { printf(“%f %f %f \n”,x,f(x),g);}}
微分係数の符号が変化したときのみ出力も可
2323
微分方程式の解法
€
ʹ′ f (x) = limΔx→0
f (x + Δx) − f (x)Δx
~ f (x + Δx) − f (x)Δx
€
f (x + Δx) = f (x) + Δx × ʹ′ f (x)
自由落下 for(k=1;k<kmax;k++){ t=t+dt; v=v+dt*g; x=x+dt*v;}
€
v =dxdt
€
x(t + Δt) = x(t) + Δt × v
(1)
(2)
(3)
(4)
(5)
(6)
m=1.0
€
m dvdt
= m ʹ′ v (t) = mg
€
v(t + Δt) = v(t) + Δt × g
2424
空気抵抗•速さに比例する場合
•宿題1:終端速度はmg/aである事を示せ
•速さの2乗に比例する場合
•符号に注意 v**2>0
•投げ上げ問題 でif文で分ける
•宿題2:速度の2乗の抵抗で投げ問題で次の式を示せ
for(k=0;k<?; k++){ t=t+dt; v=v+dt*(g-a*v); x=x+dt*v;}
m=1.0
€
m dvdt
= m ʹ′ v (t) = mg −α × v(t)
€
1vg2 =
1vi2 +
1v f2
vg:地上に戻った速さvi:初速vf:終端速度25
25
空気抵抗•速度に比例:終端速度~mg/a
•速度の2乗に比例:終端速度~sqrt(mg/a)
t
v
v
t
va=1.0m=1.0
2626
単振動と抵抗•単振動の微分方程式
•空気抵抗がある場合
•減衰振動を示せ
for(k=0;k<?; k++){ t=t+dt; v=v+dt*(-b*x); x=x+dt*v;}
for(k=0;k<?; k++){ v=v+dt*(-b*x-a*v); x=x+dt*v;}
€
m dvdt
= m ʹ′ v (t) = −b × x(t) −α × v(t)€
m dvdt
= m ʹ′ v (t) = −b × x(t)
t
振幅
a=0.1
2727
平面上の運動•惑星の楕円運動
•連立微分方程式 を2次元で作る
• g=1,m=1のとき r=sqrt(x*x+y*y); a=g*m/r/r; c=x/r; s=y/r; vx=vx-a*c*dt; vy=vy-a*s*dt; x=x+vx*dt; y=y+vy*dt:x
y 楕円軌道 実はyが長い
初期値x=1, y=0, vx=0, vy =?
安定軌道の初期値x=1, y=0, vx=0, vy =の最小値は?
2828
乱数•一様乱数
•乱数発生関数 rand()
• 乱数初期化 srand(int)
• rand()の最大値rmをさがせ
•最大値で割ると1以下の乱数
•自然現象の裏にあるので
•シミュレーションに使える
int r,rand();for(k=0;k<?; k++){r=rand();printf(“ %d %d \n”,k,r);}
rm=231-1=2147483647
2929
さいころ•ランダムな1-6の整数を作る道具
• ./a.out で同じ結果
• int A%6 は6で割ったあまり
•1の目の出る割合を調べよ
int r,rand();for(k=0;k<?; k++){r=rand()%6+1;printf(“ %d %d \n”,k,r);}
3030
面積計算•円の内側の個数nを数える
• n/M はr=3.14159/4srand(int)for(k=0;k<M; k++){ x=rand()/rm; y=rand()/rm; r=sqrt(x*x+y*y); if (r<1.) n=n+1;}
正方形内の個数
0<x<1.0, 0<y<1.0
x
y
1.0
1.0
0.0
乱数の応用
n個
M個
3131
面積計算問題
•楕円の面積を計算せよ
• の面積はrab
•一様乱数z=rand()/rm は 0~1なので
• -a~aまでの一様乱数を作るには a>0
• x=a*(2.0*z-1.0)とする
a
€
x 2
a2+y 2
b2=1
x
y
-a-b
b
3232
面積計算•関数の面積=積分
•関数の積分領域より
•広い領域内に一様乱数
•を生成する
•そのうち関数より小さい物の数を数えて
•割り合いを計算する
•精度は悪いがどんな形にも適用可
y=f(x)
xa
f(x)
s
b
c
3333
よっぱらいの歩み srand(int)for(k=0;k<?; k++)r=rand()/rm;if(r<0.5) x=x+1;else x=x-1;printf(“ %d %d \n”,k,x);}歩数k
位置x
左へひっくり返りそうなよっぱらい
•乱数の応用:1次元xよっぱらい
•実数 乱数r 0<= r <=1
• r<0.5 なら右へ:x=x+1
• r>=0.5 なら左へ:x=x-1
•複数のよっぱらいのある歩数での到着地点の平均値と標準偏差
ランダム
3434
2次元でのよっぱらい•座標を2つ用意 x,y
• 2次元平面内で4通りの選択肢
•乱数x 0<x<1
• 0.<=x<0.25 なら右へ、0.25<=x<0.5なら左へ
• 0.5<=x<0.75 なら上へ、0.75<=x<1.なら下へ
• N歩で到着する点は中心からの距離R、Rの分布と平均値は?
y
x
3535
2次元よっぱらい•原点から出発、1歩を4通りからランダムに選択
•100歩あるいたら1000人の到着点分布
中心が多い
3636
配列array a[3]
• 3成分ベクトルaをa[3]とかく
• 2つのベクトルの内積xを計算
•同様に外積も計算できる
float a[3],b[3];a[0]= ;a[1]= ;a[2]= ;b[0]= ;b[1]= ;b[2]= ;x=0.0;for(i=0;i<3; i++){x=x+a[i]*b[i];}37
37
histogram•ヒストグラムの整数配列 h(10)
• まず中身を0にする
•乱数x, int j=x*10+1
• h[j]=h[j]+1 :1個加える
int h[10];for(k=0;k<10; k++){h[k]=0;}srand(?)for(k=0;k<?; k++){ x=rand()/rm;int j=x*10;h[j]=h[j]+1;}
for(k=0;k<10; k++){printf(“ %d %d \n”,k,h[k]);}
bin数10
j番目のビンに
h[j]の中身は何回1がたされたか
3838
一様乱数•x=rand()/rm は一様乱数
•その意味は、xの分布が0.~1.で一様
•これをテスト
x
h[]h[0]=101h[1]=111h[2]=82.......h[8]=97h[9]=89
with step39
39
中心極限定理
<x>0.5
• N個の一様乱数の平均の分布
•分布の平均値は一様分布の平均
•分布の標準偏差は
•一様分布の標準偏差の
• 1/sqrt(N)になる
•これを示せ
1.00.0
gauss分布
gnuplot “ ” with step
4040
中心極限定理•2つのガウス分布(1,2)の和の分布はガウス分布(3)である事を示せ
•平均値m3=m2+m1
•標準偏差s3=sqrt(s2*s2+s1*s1)
4141
コンデンサーの電場•Laplace eq. 2次元 50x50のメッシュ
•座標交点のポテンシャル V[int x][int y]
• 境界条件:中に棒1本 V=V+
•箱の周りはゼロ
• V[10][any]=0., V[any][0]=0.
• V[50][any]=0., V[any][50]=0.
x
y
01,2,... 50
50.
.
.2 10
V+
20 30
2次元配列
4242
for( i=0;i<51;i++) /* clear array */ { for (j=0;j<51;j++) { v[i][j] = 0.0; }}
vl=v[x-1][y];vr=v[x+1][y];vu=v[x ][y+1];vd=v[x ][y-1];v[x][y]=(vl+vr+vu+vd)/4.0 ;
初期化:全空間のポテンシャルを0に
境界条件:周囲も0
ラプラス差分方程式:実はある点の周りのポテンシャルの平均を取る事
xx+1
x-1y y+1y-1
4343
Laplace equation
V(x,y)=(周りの4つのVの和)/4
差分(偏微分)
二回の差分
xx+d
x-dy y+ dy-d44
44
x yy
V(x,y)
1本コンデンサーの電位(ポテンシャル:V)
splot 45
45