投稿者:mike
投稿日:2017年 1月11日(水)13時36分22秒
|
|
|
初投稿です。
分子動力学法による箱の中のArの運動のシミュレーションをしています。
以下に添付したdecimal basicのプログラムを動かしてみると、
windows (ver 7.7.8)では比較的滑らかに粒子が動くのですが、
mac (ver 0.6.5.2)では、ぎくしゃくとした動きをします。
対策はあるのでしょうか?
ご教示いただければ幸いです。
---------------
!
! ========= molecular dynamics 2D ==========
!
! ArGasMD2D.bas
! Mitsuru Ikeuchi
!
! ver 0.0.0 2017.01.11
!
DECLARE EXTERNAL NUMERIC md2d.sysTime ! system time
DECLARE EXTERNAL SUB md2d.setInitialCondition
DECLARE EXTERNAL SUB md2d.moveParticles
DECLARE EXTERNAL SUB md2d.drawParticles
DECLARE EXTERNAL FUNCTION md2d.sysTemp
!
CALL setInitialCondition
CALL drawParticles(100)
!
FOR it=1 TO 1000
FOR i=1 TO 20
CALL moveParticles
NEXT i
CALL drawParticles(100)
!IF (MOD(it,10)=0) THEN
! PRINT USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
!END IF
NEXT it
!
END
!
! ---------- md2d module ----------
!
MODULE md2d
PUBLIC NUMERIC sysTime
PUBLIC SUB setInitialCondition,moveParticles,drawParticles
PUBLIC FUNCTION sysTemp
SHARE NUMERIC dt,Nmt, xMax, yMax, sigm, mass, epsi, mag
SHARE NUMERIC xx(100),yy(100),vx(100),vy(100),ffx(100),ffy(100)
! xx(i),yy(i) : position of i-th paryicle
! vx(i),vy(i) : velocity of i-th paryicle
! ffx(i),ffy(i): force of i-th paryicle
LET sysTime = 0.0 ! system time (s)
LET dt = 20.0*1.0e-15 ! time step (s)
LET Nmt=36 ! number of particles
LET xMax =6.0E-9 ! x-Box size (m)
LET yMax =6.0E-9 ! y-Box size (m)
LET mass = 39.95*1.67e-27 ! mass of Ar (kg)
LET sigm = 3.40e-10 ! L-J potential sigma for Ar (m)
LET epsi = 1.67e-21 ! L-J potential epsilon FOR Ar (J)
LET mag = 1.0E9 ! (view scale(m)) = mag x (particle scale(nm))
!
EXTERNAL SUB setInitialCondition
DECLARE EXTERNAL SUB ajustV
! set particles
RANDOMIZE
LET s = xMax/7.0
FOR i=1 TO Nmt
LET xx(i) = s*MOD((i-1),6)+1.0*s
LET yy(i) = s*int((i-1)/6)+1.0*s
LET vx(i) = 500.0*(RND-0.5)
LET vy(i) = 500.0*(RND-0.5)
LET ffx(i) = 0.0
LET ffy(i) = 0.0
NEXT i
CALL ajustV(150)
! set window
LET b=2
SET WINDOW -b,xMax*mag+b,-b,yMax*mag+b
!
END SUB
!
EXTERNAL SUB moveParticles
DECLARE EXTERNAL SUB calcForce
LET a = 0.5*dt/mass
FOR i=1 TO Nmt
!LET a = 0.5*dt/mass
LET vx(i) = vx(i)+a*ffx(i)
LET vy(i) = vy(i)+a*ffy(i)
LET xx(i) = xx(i)+vx(i)*dt
LET yy(i) = yy(i)+vy(i)*dt
NEXT i
CALL calcForce
FOR i=1 TO Nmt
!LET a = 0.5*dt/mass
LET vx(i) = vx(i)+a*ffx(i)
LET vy(i) = vy(i)+a*ffy(i)
NEXT i
! set boundary
FOR i=1 TO Nmt
if (xx(i) < 0.0) then
LET xx(i) = 0.0 ! -xx(i)
LET vx(i) = -vx(i)
END IF
IF (xx(i) > xMax) THEN
LET xx(i) = xMax ! 2*xMax-xx(i)
LET vx(i) = -vx(i)
END IF
if (yy(i) < 0.0) then
LET yy(i) = 0.0 ! -yy(i)
LET vy(i) = -vy(i)
END IF
if (yy(i) > yMax) then
LET yy(i) = yMax ! 2*yMax-yy(i)
LET vy(i) = -vy(i)
END IF
NEXT i
LET sysTime=sysTime+dt
END sub
!
EXTERNAL SUB calcForce
DECLARE EXTERNAL FUNCTION force
FOR i=1 TO Nmt
LET ffx(i) = 0.0
LET ffy(i) = 0.0
NEXT i
FOR i=1 TO Nmt-1
FOR j=i+1 TO Nmt
LET xij = xx(i)-xx(j)
LET yij = yy(i)-yy(j)
LET rij = SQR(xij*xij+yij*yij)
LET f = force(rij)
LET fxij = f*xij/rij
LET fyij = f*yij/rij
LET ffx(i) = ffx(i)+fxij
LET ffy(i) = ffy(i)+fyij
LET ffx(j) = ffx(j)-fxij
LET ffy(j) = ffy(j)-fyij
NEXT j
NEXT i
END sub
!
EXTERNAL function force(r) ! force(r) = -dV(r)/dr
LET ri = sigm/r
LET r6 = ri^6
LET force = (24.0*epsi*r6*(2.0*r6-1.0)/r)
END function
!
! utility
!
EXTERNAL FUNCTION sysTemp
LET k = 1.38e-23 ! Boltzman's constant (J/K)
LET totalEnergy = 0.0
FOR i=1 TO Nmt
LET totalEnergy = totalEnergy + 0.5*mass*(vx(i)^2+vy(i)^2)
NEXT i
LET sysTemp = totalEnergy/(Nmt*k)
END FUNCTION
!
EXTERNAL SUB ajustV(temp)
DECLARE EXTERNAL FUNCTION sysTemp
LET r = sqr(temp/sysTemp)
FOR i=1 TO Nmt
LET vx(i) = r*vx(i)
LET vy(i) = r*vy(i)
NEXT i
END sub
!
! display
!
EXTERNAL SUB drawParticles(vmag)
DECLARE EXTERNAL FUNCTION sysTemp
LET t1 = vmag*dt
LET b = (sigm/2)*mag
!
SET DRAW MODE HIDDEN
CLEAR
SET LINE COLOR 1 ! black : wall
PLOT LINES: -b,-b; xMax*mag+b,-b; xMax*mag+b,yMax*mag+b; -b,yMax*mag+b; -b,-b
!
FOR i=1 TO Nmt
SET COLOR 2 ! blue : position
DRAW circle WITH SCALE(sigm/2.0*1E9)*SHIFT(xx(i)*mag,yy(i)*mag)
SET LINE COLOR 4 ! red : velocity
PLOT LINES: xx(i)*mag,yy(i)*mag;
PLOT LINES: (xx(i)+vx(i)*t1)*mag,(yy(i)+vy(i)*t1)*mag
SET LINE COLOR 1 ! black : force
PLOT LINES: xx(i)*mag,yy(i)*mag;
PLOT LINES: (xx(i)+0.1*ffx(i)*t1*t1/mass)*mag,(yy(i)+0.1*ffy(i)*t1*t1/mass)*mag
NEXT i
!
SET TEXT COLOR 1 ! black
PLOT TEXT, AT 0,-0.7,USING "box size =##.# x ##.# (nm)":xMax*mag,yMax*mag
PLOT TEXT, AT 0,-1 ,USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
PLOT TEXT, AT 0,-1.3 :"Ar in the box (2-dimensional molecular dynamics)"
!
SET LINE COLOR 4 ! red : velocity
LET xPos = xMax*mag*0.5+1
LET yPos = yMax*mag+1
PLOT LINES: xPos,yPos;xPos+0.5,yPos
SET TEXT COLOR 4 ! red
PLOT TEXT, AT xPos+0.7,yPos-0.05: "velosity"
SET LINE COLOR 1 ! black : velocity
PLOT LINES: xPos,yPos-0.3;xPos+0.5,yPos-0.3
SET TEXT COLOR 1 ! black
PLOT TEXT, AT xPos+0.7,yPos-0.35: "force"
!
SET DRAW MODE EXPLICIT
END SUB
!
END MODULE
!
!
! end of file
|
|
|
投稿者:白石和夫
投稿日:2017年 1月11日(水)15時50分29秒
|
|
|
> No.4212[元記事へ]
mikeさんへのお返事です。
Windows版はPLOT文の実行と同時に結果が表示されますが,
MAC版は33m秒ごとに表示を更新します。
おそらく,これが理由だと思います。
33m秒という数値を小さくすれば動きはスムーズになります。
MAC版にはソースコードを同梱しているので,再構築すれば可能ですが,
MACはLazarusを動かすまでが大変です・・・・・。
画面表示書き換えレートを決定しているのは,
paintfrm.lfmをメモ帳などで開くとほぼ最後にある,
object Timer1: TTimer
Interval = 33
OnTimer = Timer1Timer
の部分です。
> 初投稿です。
>
> 分子動力学法による箱の中のArの運動のシミュレーションをしています。
> 以下に添付したdecimal basicのプログラムを動かしてみると、
> windows (ver 7.7.8)では比較的滑らかに粒子が動くのですが、
> mac (ver 0.6.5.2)では、ぎくしゃくとした動きをします。
> 対策はあるのでしょうか?
> ご教示いただければ幸いです。
>
> ---------------
>
> !
> ! ========= molecular dynamics 2D ==========
> !
> ! ArGasMD2D.bas
> ! Mitsuru Ikeuchi
> !
> ! ver 0.0.0 2017.01.11
> !
>
> DECLARE EXTERNAL NUMERIC md2d.sysTime ! system time
> DECLARE EXTERNAL SUB md2d.setInitialCondition
> DECLARE EXTERNAL SUB md2d.moveParticles
> DECLARE EXTERNAL SUB md2d.drawParticles
> DECLARE EXTERNAL FUNCTION md2d.sysTemp
> !
> CALL setInitialCondition
> CALL drawParticles(100)
> !
> FOR it=1 TO 1000
> FOR i=1 TO 20
> CALL moveParticles
> NEXT i
> CALL drawParticles(100)
> !IF (MOD(it,10)=0) THEN
> ! PRINT USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
> !END IF
> NEXT it
> !
> END
>
> !
> ! ---------- md2d module ----------
> !
> MODULE md2d
> PUBLIC NUMERIC sysTime
> PUBLIC SUB setInitialCondition,moveParticles,drawParticles
> PUBLIC FUNCTION sysTemp
> SHARE NUMERIC dt,Nmt, xMax, yMax, sigm, mass, epsi, mag
> SHARE NUMERIC xx(100),yy(100),vx(100),vy(100),ffx(100),ffy(100)
> ! xx(i),yy(i) : position of i-th paryicle
> ! vx(i),vy(i) : velocity of i-th paryicle
> ! ffx(i),ffy(i): force of i-th paryicle
> LET sysTime = 0.0 ! system time (s)
> LET dt = 20.0*1.0e-15 ! time step (s)
> LET Nmt=36 ! number of particles
> LET xMax =6.0E-9 ! x-Box size (m)
> LET yMax =6.0E-9 ! y-Box size (m)
> LET mass = 39.95*1.67e-27 ! mass of Ar (kg)
> LET sigm = 3.40e-10 ! L-J potential sigma for Ar (m)
> LET epsi = 1.67e-21 ! L-J potential epsilon FOR Ar (J)
> LET mag = 1.0E9 ! (view scale(m)) = mag x (particle scale(nm))
> !
> EXTERNAL SUB setInitialCondition
> DECLARE EXTERNAL SUB ajustV
> ! set particles
> RANDOMIZE
> LET s = xMax/7.0
> FOR i=1 TO Nmt
> LET xx(i) = s*MOD((i-1),6)+1.0*s
> LET yy(i) = s*int((i-1)/6)+1.0*s
> LET vx(i) = 500.0*(RND-0.5)
> LET vy(i) = 500.0*(RND-0.5)
> LET ffx(i) = 0.0
> LET ffy(i) = 0.0
> NEXT i
> CALL ajustV(150)
> ! set window
> LET b=2
> SET WINDOW -b,xMax*mag+b,-b,yMax*mag+b
> !
> END SUB
> !
> EXTERNAL SUB moveParticles
> DECLARE EXTERNAL SUB calcForce
> LET a = 0.5*dt/mass
> FOR i=1 TO Nmt
> !LET a = 0.5*dt/mass
> LET vx(i) = vx(i)+a*ffx(i)
> LET vy(i) = vy(i)+a*ffy(i)
> LET xx(i) = xx(i)+vx(i)*dt
> LET yy(i) = yy(i)+vy(i)*dt
> NEXT i
> CALL calcForce
> FOR i=1 TO Nmt
> !LET a = 0.5*dt/mass
> LET vx(i) = vx(i)+a*ffx(i)
> LET vy(i) = vy(i)+a*ffy(i)
> NEXT i
> ! set boundary
> FOR i=1 TO Nmt
> if (xx(i) < 0.0) then
> LET xx(i) = 0.0 ! -xx(i)
> LET vx(i) = -vx(i)
> END IF
> IF (xx(i) > xMax) THEN
> LET xx(i) = xMax ! 2*xMax-xx(i)
> LET vx(i) = -vx(i)
> END IF
> if (yy(i) < 0.0) then
> LET yy(i) = 0.0 ! -yy(i)
> LET vy(i) = -vy(i)
> END IF
> if (yy(i) > yMax) then
> LET yy(i) = yMax ! 2*yMax-yy(i)
> LET vy(i) = -vy(i)
> END IF
> NEXT i
> LET sysTime=sysTime+dt
> END sub
> !
> EXTERNAL SUB calcForce
> DECLARE EXTERNAL FUNCTION force
> FOR i=1 TO Nmt
> LET ffx(i) = 0.0
> LET ffy(i) = 0.0
> NEXT i
> FOR i=1 TO Nmt-1
> FOR j=i+1 TO Nmt
> LET xij = xx(i)-xx(j)
> LET yij = yy(i)-yy(j)
> LET rij = SQR(xij*xij+yij*yij)
> LET f = force(rij)
> LET fxij = f*xij/rij
> LET fyij = f*yij/rij
> LET ffx(i) = ffx(i)+fxij
> LET ffy(i) = ffy(i)+fyij
> LET ffx(j) = ffx(j)-fxij
> LET ffy(j) = ffy(j)-fyij
> NEXT j
> NEXT i
> END sub
> !
> EXTERNAL function force(r) ! force(r) = -dV(r)/dr
> LET ri = sigm/r
> LET r6 = ri^6
> LET force = (24.0*epsi*r6*(2.0*r6-1.0)/r)
> END function
> !
> ! utility
> !
> EXTERNAL FUNCTION sysTemp
> LET k = 1.38e-23 ! Boltzman's constant (J/K)
> LET totalEnergy = 0.0
> FOR i=1 TO Nmt
> LET totalEnergy = totalEnergy + 0.5*mass*(vx(i)^2+vy(i)^2)
> NEXT i
> LET sysTemp = totalEnergy/(Nmt*k)
> END FUNCTION
> !
> EXTERNAL SUB ajustV(temp)
> DECLARE EXTERNAL FUNCTION sysTemp
> LET r = sqr(temp/sysTemp)
> FOR i=1 TO Nmt
> LET vx(i) = r*vx(i)
> LET vy(i) = r*vy(i)
> NEXT i
> END sub
> !
> ! display
> !
> EXTERNAL SUB drawParticles(vmag)
> DECLARE EXTERNAL FUNCTION sysTemp
> LET t1 = vmag*dt
> LET b = (sigm/2)*mag
> !
> SET DRAW MODE HIDDEN
> CLEAR
> SET LINE COLOR 1 ! black : wall
> PLOT LINES: -b,-b; xMax*mag+b,-b; xMax*mag+b,yMax*mag+b; -b,yMax*mag+b; -b,-b
> !
> FOR i=1 TO Nmt
> SET COLOR 2 ! blue : position
> DRAW circle WITH SCALE(sigm/2.0*1E9)*SHIFT(xx(i)*mag,yy(i)*mag)
> SET LINE COLOR 4 ! red : velocity
> PLOT LINES: xx(i)*mag,yy(i)*mag;
> PLOT LINES: (xx(i)+vx(i)*t1)*mag,(yy(i)+vy(i)*t1)*mag
> SET LINE COLOR 1 ! black : force
> PLOT LINES: xx(i)*mag,yy(i)*mag;
> PLOT LINES: (xx(i)+0.1*ffx(i)*t1*t1/mass)*mag,(yy(i)+0.1*ffy(i)*t1*t1/mass)*mag
> NEXT i
> !
> SET TEXT COLOR 1 ! black
> PLOT TEXT, AT 0,-0.7,USING "box size =##.# x ##.# (nm)":xMax*mag,yMax*mag
> PLOT TEXT, AT 0,-1 ,USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
> PLOT TEXT, AT 0,-1.3 :"Ar in the box (2-dimensional molecular dynamics)"
> !
> SET LINE COLOR 4 ! red : velocity
> LET xPos = xMax*mag*0.5+1
> LET yPos = yMax*mag+1
> PLOT LINES: xPos,yPos;xPos+0.5,yPos
> SET TEXT COLOR 4 ! red
> PLOT TEXT, AT xPos+0.7,yPos-0.05: "velosity"
> SET LINE COLOR 1 ! black : velocity
> PLOT LINES: xPos,yPos-0.3;xPos+0.5,yPos-0.3
> SET TEXT COLOR 1 ! black
> PLOT TEXT, AT xPos+0.7,yPos-0.35: "force"
> !
> SET DRAW MODE EXPLICIT
> END SUB
> !
> END MODULE
> !
> !
> ! end of file
>
|
|
|
投稿者:mike
投稿日:2017年 1月11日(水)18時03分41秒
|
|
|
> No.4213[元記事へ]
白石和夫さんへのお返事です。
白石先生、ご回答ありがとうございます。
basic処理系自体を改造するのは、敷居が高く、
Object Pascalの使用経験がありませんので、
時間がかかりそうです。
当面はwindows限定で使っていきます。
BASIC Acceleratorも使わせていただきたいので、
windowsの方にLazarusを入れようと考えています。
Acceleratorが使えるようになったら、
Object Pascalを学びたいと思います。
今後とも、よろしくお願いします。
> mikeさんへのお返事です。
>
> Windows版はPLOT文の実行と同時に結果が表示されますが,
> MAC版は33m秒ごとに表示を更新します。
> おそらく,これが理由だと思います。
> 33m秒という数値を小さくすれば動きはスムーズになります。
> MAC版にはソースコードを同梱しているので,再構築すれば可能ですが,
> MACはLazarusを動かすまでが大変です・・・・・。
>
>
> 画面表示書き換えレートを決定しているのは,
> paintfrm.lfmをメモ帳などで開くとほぼ最後にある,
>
> object Timer1: TTimer
> Interval = 33
> OnTimer = Timer1Timer
>
> の部分です。
>
|
|
|
投稿者:白石和夫
投稿日:2017年 1月11日(水)18時36分57秒
|
|
|
> No.4214[元記事へ]
mikeさんへのお返事です。
実際に必要なことは,Object Pascalを学ぶことではなくて,操作手順だけです。
ソースを書き換えたらLazarusを起動して,
プロジェクトメニューから「プロジェクトを開く」でBASIC.lprを読み込んで
実行メニューでコンパイルを実行すればOkです。ただし,Macだと,
コンパイルした後,出来上がった実行ファイルを,.appの中に埋め込むのが面倒です。
(知らないと不可解)
> 白石和夫さんへのお返事です。
>
> 白石先生、ご回答ありがとうございます。
> basic処理系自体を改造するのは、敷居が高く、
> Object Pascalの使用経験がありませんので、
> 時間がかかりそうです。
> 当面はwindows限定で使っていきます。
> BASIC Acceleratorも使わせていただきたいので、
> windowsの方にLazarusを入れようと考えています。
> Acceleratorが使えるようになったら、
> Object Pascalを学びたいと思います。
>
> 今後とも、よろしくお願いします。
>
>
> > mikeさんへのお返事です。
> >
> > Windows版はPLOT文の実行と同時に結果が表示されますが,
> > MAC版は33m秒ごとに表示を更新します。
> > おそらく,これが理由だと思います。
> > 33m秒という数値を小さくすれば動きはスムーズになります。
> > MAC版にはソースコードを同梱しているので,再構築すれば可能ですが,
> > MACはLazarusを動かすまでが大変です・・・・・。
> >
> >
> > 画面表示書き換えレートを決定しているのは,
> > paintfrm.lfmをメモ帳などで開くとほぼ最後にある,
> >
> > object Timer1: TTimer
> > Interval = 33
> > OnTimer = Timer1Timer
> >
> > の部分です。
> >
|
|
|
投稿者:mike
投稿日:2017年 1月11日(水)19時42分58秒
|
|
|
> No.4215[元記事へ]
白石和夫さんへのお返事です。
白石先生、ありがとうございます。
> 実際に必要なことは,Object Pascalを学ぶことではなくて,操作手順だけです。
> ソースを書き換えたらLazarusを起動して,
> プロジェクトメニューから「プロジェクトを開く」でBASIC.lprを読み込んで
> 実行メニューでコンパイルを実行すればOkです。
了解です。
> ただし,Macだと,
> コンパイルした後,出来上がった実行ファイルを,.appの中に埋め込むのが面倒です。
> (知らないと不可解)
これに関しては全く知りませんので、残念ながら諦めます。
まずは、windowsの方にLazarusをインストールし、
BASIC Acceleratorを使えるようになろうと思います。
macのぎくしゃくとした動きを見ていると、33msより長い間停止したように見える場合があります。
ガベージコレクタが関係している可能性はないでしょうか?
|
|
|
投稿者:SECOND
投稿日:2017年 1月11日(水)21時31分2秒
|
|
|
mikeさんへのお返事です。
!------------------------------------------------------
! 2014年頃に投稿していたものですが、役に立てばと、
! 少し手を加えて似たような動きにしてみました。
!
! 自由に改造、コピーして使って下さい。
!
! 高速に動かす書き方で、症状の解消になれれば、・・?
!------------------------------------------------------
!※2017.1.12 追加編集:速いパソコンは、force 表示が見えないので、保持時間を付けた。
OPTION ARITHMETIC COMPLEX !複素数モード
LET wb=400 !枠の幅
LET hb=400 !枠の高さ
SET bitmap SIZE wb+101, hb+101
SET WINDOW -50,wb+50, -50,hb+50 !左端,右端, 下端,上端
!------------------------------------------------------
RANDOMIZE 5 !引数を取ると、再現しない。
!
LET n=36 !球の数
DIM p(n) !球の座標
DIM vp(n), vpb(n), cnt(n),fce(n) !球の速度, 1ステップ前の球の速度, force保持タイマ, force記憶
DIM m(n), r(n) !球の重量、半径
FOR i=1 TO n
LET m(i)=INT(RND*2)+.5 !球の重量データー ( .5 と 1.5 の2種類 )
LET r(i)=10*m(i)^(1/3) !半径 r ∝ 重量の3乗根。
NEXT i
!
SET COLOR MIX(0) 0,0,0 !CLEAR 文で黒にする。
SET COLOR MIX(1) 1,1,1 !text,line, 初期カラーを白にする。
LET dt=0.2 !サンプリングタイム ※調整 小さくする→遅くなる
!
!----- 重ならない初期位置のランダム設定
LET j=1
DO
LET p(j)=COMPLEX( r(j)+2+(wb-2*r(j)-4)*RND, r(j)+2+(hb-2*r(j)-4)*RND)
FOR i=1 TO j-1
IF ABS(p(i)-p(j))< r(i)+r(j)+3 THEN EXIT FOR !オーバーラップ: 再試行
NEXT i
IF j<=i THEN LET j=j+1 !Ok: j+1
LOOP UNTIL n< j
!-----
DO
LET j=0
FOR i=1 TO n
LET vp(i)=COMPLEX((RND-0.5)*40, (RND-0.5)*40) !初期速度設定
LET j=j+ABS(vp(i))
NEXT i
LOOP UNTIL SQR(n)*20< j
!-----
DO
MAT vpb=vp ! $$$ force
FOR i=1 TO n
LET p(i)=p(i)+vp(i)*dt
!---
IF re(p(i))< r(i) AND re(vp(i))< 0 THEN !左の枠に衝突
LET vp(i)= -conj(vp(i))
LET p(i)= COMPLEX(r(i),im(p(i)))
ELSEIF wb-r(i)< re(p(i)) AND 0< re(vp(i)) THEN !右の枠に衝突
LET vp(i)= -conj(vp(i))
LET p(i)= COMPLEX(wb-r(i),im(p(i)))
ELSEIF im(p(i))< r(i) AND im(vp(i))< 0 THEN !下の枠に衝突
LET vp(i)= conj(vp(i))
LET p(i)= COMPLEX(re(p(i)),r(i))
ELSEIF hb-r(i)< im(p(i)) AND 0< im(vp(i)) THEN !上の枠に衝突
LET vp(i)= conj(vp(i))
LET p(i)= COMPLEX(re(p(i)),hb-r(i))
END IF
!---
CALL collide !球同士の衝突
NEXT i
!
SET DRAW mode hidden !表示画、更新の一時停止。
CLEAR !全画面、黒で、塗りつぶす
PLOT TEXT,AT wb*.8,hb+20:"右クリック終了"
SET LINE width 2 ! $$$ velocity, force
FOR i=1 TO n
SET AREA COLOR i
DRAW disk WITH SCALE(r(i))*SHIFT(p(i)) !球の表示
SET LINE COLOR 4 ! $$$ velocity
PLOT LINES: p(i); p(i)+vp(i) ! $$$ velocity
!--
LET cnt(i)=cnt(i)-1 ! $$$
IF cnt(i)<=0 OR EPS(0)< ABS(vp(i)-vpb(i)) THEN ! $$$
LET fce(i)=(vp(i)-vpb(i))*m(i) ! $$$ force 表示の更新
LET cnt(i)=10 ! $$$ force 表示の保持時間 ※大→長い
END IF ! $$$
!--
SET LINE COLOR 1 ! $$$ force
PLOT LINES: p(i); p(i)+fce(i) ! $$$ force
NEXT i
SET LINE width 4
SET LINE COLOR 6
PLOT LINES: 0; wb; COMPLEX(wb,hb); COMPLEX(0,hb); 0 !枠の表示
SET DRAW mode explicit !表示画、常時更新の再開。
!
WAIT DELAY .01 !節電。削除すると、かなり速くなる
mouse poll mox,moy,mlb,mrb
LOOP UNTIL 0< mrb
!-----------------------------------------------------------
! 球同士の衝突( 表面摩擦0、異なる質量)
!
! ※反射速度は、法線ベクトルの内外向き、接線ベクトルの回転向き、
! などの影響を受けないが、法線上の 相対的速さ は、極性に反映。
!-----------------------------------------------------------
SUB collide
FOR j=1 TO n
IF i<>j THEN
LET l=ABS( p(i) -p(j) ) !球(i)(j)間距離
IF l<=r(i)+r(j) THEN !距離が範囲内、衝突の前 後?
LET np=(p(j)-p(i))/l !接触点 法線単位ベクトル
LET vni=re(conj(np)*vp(i)) !接触点 法線方向の 球(i)速さ(+-)
LET vnj=re(conj(np)*vp(j)) ! 〃 球(j)速さ(+-)
IF vnj-vni< 0 THEN !法線上、相対的速さ(+-)、衝突の前、確定。
LET w=((m(i)-m(j))*vni+2*m(j)*vnj)/(m(i)+m(j)) !球(i)
LET vnj=((m(j)-m(i))*vnj+2*m(i)*vni)/(m(i)+m(j)) !球(j) 反射後の速さ
LET vni=w
LET tp=np*COMPLEX(0,1) ! 〃 接線単位ベクトル
LET vti=re(conj(tp)*vp(i)) ! 接線方向の 球(i)速さ(+-)
LET vtj=re(conj(tp)*vp(j)) ! 〃 球(j)速さ(+-)
!--
LET vp(i)= vni*np +vti*tp !球(i)速度ベクトル
LET vp(j)= vnj*np +vtj*tp !球(j)速度ベクトル
END IF
END IF
END IF
NEXT j
END SUB
END
|
|
|
投稿者:mike
投稿日:2017年 1月12日(木)06時46分16秒
|
|
|
> No.4217[元記事へ]
SECONDさんへのお返事です。
SECONDさん、ありがとうございます。
複素数を用いたスッキリとしたコードに感心しました。
2次元の数のペアと複素数の対応が非常にうまくいっているのに目から鱗です。
グラフィックのステートメントと複素数の引数の整合性もよいですね。
ただ、3次元への拡張についてはよくわかりません。
配列の配列が使えると、3次元でもスッキリとした記述ができそうですが...。
表示の滑らかさを見るため、SECONDさんのプログラムの一部を下記のように変更(改悪)しました。
(dt=0.2-->0.01, 球の動きの部分の20回のくりかえし、WAIT DELAY .01 のコメントアウト)
このプログラムをmacで実行してみると、かなり滑らかに動きます。
ただ、時々、同じ速度にも関わらず速度が落ちたようにみえる時がありました。
ガベージコレクションかな?....。
SECONDさんのプログラムでは剛体球の衝突計算は計算量O(N)であるのに対し、
mikeのプログラムは力が遠くからも及ぶため、すべての粒子との相互作用を計算しているため、
計算量O(N^2)になっています。(一定距離以上の力を無視することでO(N)にすることは可能)
さらに相互作用ポテンシャルが短い距離で大きく変わるため、dtを小さくしないと計算が破綻
するため、どうしても遅い動きになってしまいます。
ガベージコレクションがどんなタイミングで起こるかは解りませんが、
計算量が多いほど、ポインター渡しより値渡しが多いほど・頻繁に起こると思います。
これへの対策については残念ながら考えつきません。
!------------------------------------------------------
! 2014年頃に投稿していたものですが、役に立てばと、
! 少し手を加えて似たような動きにしてみました。
!
! 自由に改造、コピーして使って下さい。
!
! 高速に動かす書き方で、症状の解消になれれば、・・?
!------------------------------------------------------
!※2017.1.12 追加編集:速いパソコンは、force 表示が見えないので、保持時間を付けた。
OPTION ARITHMETIC COMPLEX !複素数モード
LET wb=400 !枠の幅
LET hb=400 !枠の高さ
SET bitmap SIZE wb+101, hb+101
SET WINDOW -50,wb+50, -50,hb+50 !左端,右端, 下端,上端
!------------------------------------------------------
RANDOMIZE 5 !引数を取ると、再現しない。
!
LET n=36 !球の数
DIM p(n) !球の座標
DIM vp(n), vpb(n), cnt(n),fce(n) !球の速度, 1ステップ前の球の速度, force保持タイマ, force記憶
DIM m(n), r(n) !球の重量、半径
FOR i=1 TO n
LET m(i)=INT(RND*2)+.5 !球の重量データー ( .5 と 1.5 の2種類 )
LET r(i)=10*m(i)^(1/3) !半径 r ∝ 重量の3乗根。
NEXT i
!
SET COLOR MIX(0) 0,0,0 !CLEAR 文で黒にする。
SET COLOR MIX(1) 1,1,1 !text,line, 初期カラーを白にする。
LET dt=0.01 !サンプリングタイム ※調整 小さくする→遅くなる ************ change 0.2->0.01
!
!----- 重ならない初期位置のランダム設定
LET j=1
DO
LET p(j)=COMPLEX( r(j)+2+(wb-2*r(j)-4)*RND, r(j)+2+(hb-2*r(j)-4)*RND)
FOR i=1 TO j-1
IF ABS(p(i)-p(j))< r(i)+r(j)+3 THEN EXIT FOR !オーバーラップ: 再試行
NEXT i
IF j<=i THEN LET j=j+1 !Ok: j+1
LOOP UNTIL n< j
!-----
DO
LET j=0
FOR i=1 TO n
LET vp(i)=COMPLEX((RND-0.5)*40, (RND-0.5)*40) !初期速度設定
LET j=j+ABS(vp(i))
NEXT i
LOOP UNTIL SQR(n)*20< j
!-----
DO
MAT vpb=vp ! $$$ force
FOR ii=1 TO 20 !************************ change
FOR i=1 TO n
LET p(i)=p(i)+vp(i)*dt
!---
IF re(p(i))< r(i) AND re(vp(i))< 0 THEN !左の枠に衝突
LET vp(i)= -conj(vp(i))
LET p(i)= COMPLEX(r(i),im(p(i)))
ELSEIF wb-r(i)< re(p(i)) AND 0< re(vp(i)) THEN !右の枠に衝突
LET vp(i)= -conj(vp(i))
LET p(i)= COMPLEX(wb-r(i),im(p(i)))
ELSEIF im(p(i))< r(i) AND im(vp(i))< 0 THEN !下の枠に衝突
LET vp(i)= conj(vp(i))
LET p(i)= COMPLEX(re(p(i)),r(i))
ELSEIF hb-r(i)< im(p(i)) AND 0< im(vp(i)) THEN !上の枠に衝突
LET vp(i)= conj(vp(i))
LET p(i)= COMPLEX(re(p(i)),hb-r(i))
END IF
!---
CALL collide !球同士の衝突
NEXT i
NEXT ii !************************ change
!
SET DRAW mode hidden !表示画、更新の一時停止。
CLEAR !全画面、黒で、塗りつぶす
PLOT TEXT,AT wb*.8,hb+20:"右クリック終了"
SET LINE width 2 ! $$$ velocity, force
FOR i=1 TO n
SET AREA COLOR i
DRAW disk WITH SCALE(r(i))*SHIFT(p(i)) !球の表示
SET LINE COLOR 4 ! $$$ velocity
PLOT LINES: p(i); p(i)+vp(i) ! $$$ velocity
!--
LET cnt(i)=cnt(i)-1 ! $$$
IF cnt(i)<=0 OR EPS(0)< ABS(vp(i)-vpb(i)) THEN ! $$$
LET fce(i)=(vp(i)-vpb(i))*m(i) ! $$$ force 表示の更新
LET cnt(i)=10 ! $$$ force 表示の保持時間 ※大→長い
END IF ! $$$
!--
SET LINE COLOR 1 ! $$$ force
PLOT LINES: p(i); p(i)+fce(i) ! $$$ force
NEXT i
SET LINE width 4
SET LINE COLOR 6
PLOT LINES: 0; wb; COMPLEX(wb,hb); COMPLEX(0,hb); 0 !枠の表示
SET DRAW mode explicit !表示画、常時更新の再開。
!
!WAIT DELAY .01 !節電。削除すると、かなり速くなる ****** change
mouse poll mox,moy,mlb,mrb
LOOP UNTIL 0< mrb
!-----------------------------------------------------------
! 球同士の衝突( 表面摩擦0、異なる質量)
!
! ※反射速度は、法線ベクトルの内外向き、接線ベクトルの回転向き、
! などの影響を受けないが、法線上の 相対的速さ は、極性に反映。
!-----------------------------------------------------------
SUB collide
FOR j=1 TO n
IF i<>j THEN
LET l=ABS( p(i) -p(j) ) !球(i)(j)間距離
IF l<=r(i)+r(j) THEN !距離が範囲内、衝突の前 後?
LET np=(p(j)-p(i))/l !接触点 法線単位ベクトル
LET vni=re(conj(np)*vp(i)) !接触点 法線方向の 球(i)速さ(+-)
LET vnj=re(conj(np)*vp(j)) ! 〃 球(j)速さ(+-)
IF vnj-vni< 0 THEN !法線上、相対的速さ(+-)、衝突の前、確定。
LET w=((m(i)-m(j))*vni+2*m(j)*vnj)/(m(i)+m(j)) !球(i)
LET vnj=((m(j)-m(i))*vnj+2*m(i)*vni)/(m(i)+m(j)) !球(j) 反射後の速さ
LET vni=w
LET tp=np*COMPLEX(0,1) ! 〃 接線単位ベクトル
LET vti=re(conj(tp)*vp(i)) ! 接線方向の 球(i)速さ(+-)
LET vtj=re(conj(tp)*vp(j)) ! 〃 球(j)速さ(+-)
!--
LET vp(i)= vni*np +vti*tp !球(i)速度ベクトル
LET vp(j)= vnj*np +vtj*tp !球(j)速度ベクトル
END IF
END IF
END IF
NEXT j
END SUB
END
|
|
|
投稿者:白石和夫
投稿日:2017年 1月12日(木)09時07分37秒
|
|
|
> No.4214[元記事へ]
MAC上のBASICAccで動かしたらスムーズに動きます。
MAC上のBASICAccは,前回PLOT文を実行してから40m秒以上経過していたら描画結果を画面に反映させる
描画方法を使っています。(graphsys.pas 590行~608行)
MAC版BASICでinterval値を書き換えて実行してみましたけれど,差があるようには思えませんでした。
BASIC上でカクカクするのは単に遅いからのように思えます。
なお,interval値は,paintfrm.lfmでの設定値を,paintfrm.pas 130行目の
Timer1.Interval:=33;
で上書きしていました。
paintfrm.lfmは書き換えても無意味で,paintfrm.pas 130行の変更が必要でした。
|
|
|
投稿者:mike
投稿日:2017年 1月12日(木)11時12分28秒
|
|
|
> No.4219[元記事へ]
白石和夫さんへのお返事です。
白石先生、
ていねいにフォローいただき、ありがとうございます。
> MAC上のBASICAccで動かしたらスムーズに動きます。
BASIC Accが使えるように環境を整えようと思います。
> MAC版BASICでinterval値を書き換えて実行してみましたけれど,差があるようには思えませんでした。
> BASIC上でカクカクするのは単に遅いからのように思えます。
「ぎくしゃくとした」という表現がよくなかったようです。
windowsではカクカクと動いては見えるのですが、その時間間隔がほぼ一定です。
(古いXPマシンでも動かしてみたのすが、遅いですが時間間隔はほぼ一定でした)
一方、macではカクカクと動く時間間隔が、数秒程度に1回の割合で、感覚でわかるほど
延びてしまいます。
カクカクの方は粒子の動きの計算と描画頻度(計算20回に一度描画)を変えれば解決できそうです。
ここでは、この描画間隔の不自然な延びを解決したいのです。
|
|
|
投稿者:白石 和夫
投稿日:2017年 1月13日(金)08時18分34秒
|
|
|
mikeさんへのお返事です。
空PRINT文を書き換えてループ処理1回あたりの所用時間(秒)を測定してみました。
FOR it=1 TO 1000
PRINT it, TIME-time0
LET time0=time
実行結果の最後のほうです
970 .26
971 .24
972 .26
973 .24
974 .26
975 .28
976 .32
977 .4
978 .3
979 .23
980 .29
981 .23
982 .26
983 .23
984 .25
985 .23
986 .24
987 .26
988 .24
989 .26
990 .24
991 .24
992 .24
993 .24
994 .24
995 .25
996 .24
997 .27
998 .24
999 .29
1000 .37
同じことをファイル出力にして調べてみると、
ASK directory dir$
PRINT dir$
OPEN #1: NAME dir$&"/test002.txt"
FOR it=1 TO 1000
PRINT #1:it, TIME-time0
LET time0=time
970 .24
971 .23
972 .23
973 .23
974 .24
975 .23
976 .23
977 .23
978 .23
979 .23
980 .23
981 .24
982 .23
983 .25
984 .23
985 .24
986 .23
987 .23
988 .24
989 .25
990 .23
991 .23
992 .23
993 .24
994 .23
995 .23
996 .23
997 .23
998 .23
999 .23
1000 .23
となって、テキスト出力ウィンドウへの出力が揺らぎの原因になっていることが窺われます。
PRINTの出力先をファイルに変えれば安定するかもしれません。
MAC OS 10.6.8
2.53Ghz Intel Core 2 Duo
メモリ 4GB 1067Mhz DDR3
|
|
|
投稿者:mike
投稿日:2017年 1月13日(金)14時00分51秒
|
|
|
> No.4221[元記事へ]
白石 和夫さんへのお返事です。
TIMEを用いた所要時間の計測によって、定量化することで、問題が明確になりました。
見た感じだけで判断していたことが恥ずかしいです。
教えていただき、ありがとうございます。
> となって、テキスト出力ウィンドウへの出力が揺らぎの原因になっていることが窺われます。
> PRINTの出力先をファイルに変えれば安定するかもしれません。
なるほどですね。
しかしながら、今回のプログラムではテキスト出力ウィンドウはプログラム中では使わず、
PLOT TEXTを用いたグラフィック画面への出力のみになっています。
グラフィック画面への文字出力も似たような状況かどうか計測してみたいと思います。
なお、私が使っているmacは下記のものです。
decimal BASIC 0.6.5.2
MAC OS 10.7.5
2.7Ghz Intel Core i7
メモリ 4GB 1333Mhz DDR3
|
|
|
投稿者:mike
投稿日:2017年 1月14日(土)12時31分52秒
|
|
|
> No.4222[元記事へ]
白石先生から教えていただいたloopの所要時間を調べてみました。
------------ ファイルへの出力
ASK directory dir$
PRINT dir$
OPEN #1: NAME dir$&"/looptime2file01.txt"
LET time0=time
FOR it=1 TO 100
FOR i=1 TO 20
CALL moveParticles
NEXT i
CALL drawParticles(100)
PRINT #1: it, TIME-time0
LET time0=TIME
!IF (MOD(it,10)=0) THEN
! PRINT USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
!END IF
NEXT it
CLOSE #1
!
END
61 .19
62 .2
63 .22
64 .26
65 .3 ***
66 .39 ***
67 .39 ***
68 .24
69 .17
70 .17
71 .14
72 .16
73 .14
74 .16
75 .17
76 .2
77 .14
78 .15
79 .14
80 .15
81 .14
82 .15
83 .14
84 .14
85 .15
86 .2
87 .43 ***
88 .2
89 .14
90 .16
91 .14
92 .16
93 .17
94 .15
95 .14
96 .14
97 .16
98 .14
99 .15
100 .14
------------ テキスト画面への出力
LET time0=time
FOR it=1 TO 100
FOR i=1 TO 20
CALL moveParticles
NEXT i
CALL drawParticles(100)
PRINT it, TIME-time0
LET time0=TIME
!IF (MOD(it,10)=0) THEN
! PRINT USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
!END IF
NEXT it
!
END
61 .15
62 .15
63 .15
64 .15
65 .15
66 .15
67 .15
68 .15
69 .17
70 .2
71 .2
72 .23
73 .28
74 .36 ***
75 .33 ***
76 .5 ***
77 .25
78 .3 ***
79 .37 ***
80 .28
81 .19
82 .34
83 .28
84 .32 ***
85 .44 ***
86 .53 ***
87 .17
88 .16
89 .17
90 .17
91 .16
92 .17
93 .17
94 .2
95 .23
96 .23
97 .3 ***
98 .35 ***
99 .39 ***
100 .4 ***
------------ グラフィック画面へのアクセスをなくす + ファイルへの出力
ASK directory dir$
PRINT dir$
OPEN #1: NAME dir$&"/looptime2file02.txt"
LET time0=time
FOR it=1 TO 100
FOR i=1 TO 20
CALL moveParticles
NEXT i
!CALL drawParticles(100) *******
PRINT #1: it, TIME-time0
LET time0=TIME
!IF (MOD(it,10)=0) THEN
! PRINT USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
!END IF
NEXT it
CLOSE #1
!
END
61 .18
62 .13
63 .13
64 .14
65 .14
66 .2
67 .17
68 .14
69 .13
70 .14
71 .13
72 .13
73 .14
74 .13
75 .14
76 .15
77 .17
78 .19
79 .19
80 .13
81 .13
82 .14
83 .13
84 .14
85 .14
86 .14
87 .15
88 .18
89 .17
90 .13
91 .13
92 .14
93 .13
94 .14
95 .13
96 .13
97 .14
98 .13
99 .15
100 .16
この結果から見ると、計算のみでは所要時間には大きな遅れはなく、
テキスト画面やグラフィック画面への出力時に何らかの遅れがあるようです。
windowsXPやwindows10ではこれらの遅れはありませんでした。
|
|
|
投稿者:白石和夫
投稿日:2017年 1月14日(土)14時01分35秒
|
|
|
同じMAC miniですが、外付けHDDに入れたOS10.9.5でテストしてみました。
前回と同じプログラムで
画面表示だと
970 .45
971 .63
972 .42
973 .46
974 .62
975 .71
976 .57
977 .85
978 .51
979 .97
980 .54
981 .8
982 .45
983 .58
984 .42
985 .43
986 .53
987 .83
988 .48
989 .97
990 .42
991 .62
992 .71
993 .6
994 .72
995 .5
996 .84
997 .45
998 .58
999 .73
1000 .5
ファイル出力の場合、
970 .45
971 .63
972 .4
973 .43
974 .67
975 .59
976 .46
977 .89
978 .46
979 .64
980 .71
981 .52
982 .8
983 .47
984 .86
985 .46
986 .6
987 .75
988 .5
989 .8
990 .42
991 .6
992 .75
993 .5
994 .83
995 .42
996 .67
997 .68
998 .57
999 .71
1000 .47
となって、OS 10.6.8に比べて倍以上遅く、揺らぎも大きくなっています。
]白石 和夫さんへのお返事です。
> mikeさんへのお返事です。
>
> 空PRINT文を書き換えてループ処理1回あたりの所用時間(秒)を測定してみました。
> FOR it=1 TO 1000
> PRINT it, TIME-time0
> LET time0=time
>
> 実行結果の最後のほうです
> 970 .26
> 971 .24
> 972 .26
> 973 .24
> 974 .26
> 975 .28
> 976 .32
> 977 .4
> 978 .3
> 979 .23
> 980 .29
> 981 .23
> 982 .26
> 983 .23
> 984 .25
> 985 .23
> 986 .24
> 987 .26
> 988 .24
> 989 .26
> 990 .24
> 991 .24
> 992 .24
> 993 .24
> 994 .24
> 995 .25
> 996 .24
> 997 .27
> 998 .24
> 999 .29
> 1000 .37
>
> 同じことをファイル出力にして調べてみると、
> ASK directory dir$
> PRINT dir$
> OPEN #1: NAME dir$&"/test002.txt"
> FOR it=1 TO 1000
> PRINT #1:it, TIME-time0
> LET time0=time
> 970 .24
> 971 .23
> 972 .23
> 973 .23
> 974 .24
> 975 .23
> 976 .23
> 977 .23
> 978 .23
> 979 .23
> 980 .23
> 981 .24
> 982 .23
> 983 .25
> 984 .23
> 985 .24
> 986 .23
> 987 .23
> 988 .24
> 989 .25
> 990 .23
> 991 .23
> 992 .23
> 993 .24
> 994 .23
> 995 .23
> 996 .23
> 997 .23
> 998 .23
> 999 .23
> 1000 .23
> となって、テキスト出力ウィンドウへの出力が揺らぎの原因になっていることが窺われます。
> PRINTの出力先をファイルに変えれば安定するかもしれません。
>
> MAC OS 10.6.8
> 2.53Ghz Intel Core 2 Duo
> メモリ 4GB 1067Mhz DDR3
>
>
|
|
|
投稿者:mike
投稿日:2017年 1月15日(日)10時38分52秒
|
|
|
> No.4224[元記事へ]
白石和夫さんへのお返事です。
白石先生、情報をありがとうございます。
windowsの場合のLOOP時間の計測結果です。
一番遅くなると考えられるテキスト画面への出力の場合です。
LET time0=time
FOR it=1 TO 100
FOR i=1 TO 20
CALL moveParticles
NEXT i
CALL drawParticles(100)
PRINT it, TIME-time0
LET time0=TIME
!IF (MOD(it,10)=0) THEN
! PRINT USING "time =####.## (ps) temp =####.## (K)":sysTime*1.0E12,sysTemp
!END IF
NEXT it
!
END
decimal BASIC Ver 7.7.8
FMV-C8230 windows XP pro
CPU intel Celeron M410 (1.46GHz) メインメモリ 1GB
61 .36
62 .36
63 .36
64 .36
65 .36
66 .36
67 .36
68 .36
69 .35
70 .36
71 .36
72 .36
73 .36
74 .36
75 .36
76 .36
77 .36
78 .36
79 .35
80 .36
81 .36
82 .36
83 .36
84 .36
85 .36
86 .36
87 .36
88 .36
89 .36
90 .35
91 .36
92 .36
93 .36
94 .36
95 .36
96 .36
97 .36
98 .36
99 .36
100 .36
decimal BASIC Ver 7.7.8
FMV-A561D windows 10 64bit
CPU intel core-i5 (2.5GHz) メインメモリ 4GB
61 .14
62 .14
63 .14
64 .14
65 .15
66 .14
67 .14
68 .14
69 .14
70 .14
71 .12
72 .12
73 .14
74 .15
75 .13
76 .15
77 .14
78 .14
79 .14
80 .14
81 .14
82 .14
83 .12
84 .12
85 .15
86 .13
87 .14
88 .14
89 .14
90 .14
91 .14
92 .14
93 .14
94 .14
95 .14
96 .14
97 .13
98 .14
99 .14
100 .14
これまでのloopの所要時間の測定結果をまとめます。
(1)「ぎくしゃくとした動き」あるいはloopの所要時間が不定期に長くなる現象は、
winndowsあるいはdecimal BASIC Ver 7.7.8では観測されないが、
macOSあるいはdecimal BASIC Ver 0.6.5.2では、テキスト画面や
ディスクやグラフィック画面に出力がある場合に観測される。
(2)出力の相手によって遅延の度合いが異なる。
(3)macOSではバージョンが上がるほど悪化する。
|
|
|
投稿者:白石和夫
投稿日:2017年 1月15日(日)10時54分6秒
|
|
|
> No.4224[元記事へ]
十進BASIC2進モードでの実行結果(ファイル出力時)です。
OS 10.6.8で実行
970 7.99999999944703E-2
971 9.00000000037835E-2
972 .120000000002619
973 .069999999999709
974 .069999999999709
975 .069999999999709
976 5.99999999976717E-2
977 .069999999999709
978 .069999999999709
979 5.99999999976717E-2
980 .069999999999709
981 6.00000000049477E-2
982 .069999999999709
983 .069999999999709
984 .069999999999709
985 5.99999999976717E-2
986 .069999999999709
987 5.00000000029104E-2
988 5.99999999976717E-2
989 5.00000000029104E-2
990 .110000000000582
991 4.99999999956344E-2
992 8.00000000017462E-2
993 5.00000000029104E-2
994 5.99999999976717E-2
995 5.99999999976717E-2
996 5.00000000029104E-2
997 8.00000000017462E-2
998 4.99999999956344E-2
999 6.00000000049477E-2
1000 5.99999999976717E-2
OS 10.9.5のとき、見た目でもときどき休む感じがあります。
970 .100000000005821
971 .129999999997381
972 .110000000000582
973 8.99999999965075E-2
974 .110000000000582
975 9.00000000037835E-2
976 .169999999998254
977 .19999999999709
978 .360000000000582
979 .100000000005821
980 9.99999999985448E-2
981 9.99999999985448E-2
982 .120000000002619
983 .129999999997381
984 .139999999999418
985 .139999999999418
986 9.00000000037835E-2
987 .19999999999709
988 .30000000000291
989 .219999999993888
990 .100000000005821
991 9.99999999985448E-2
992 9.99999999985448E-2
993 .129999999997381
994 .139999999999418
995 .130000000004657
996 .169999999998254
997 .260000000002037
998 .389999999999418
999 8.99999999965075E-2
1000 .110000000000582
|
|
|
投稿者:mike
投稿日:2017年 1月15日(日)14時41分24秒
|
|
|
> No.4226[元記事へ]
白石和夫さんへのお返事です。
白石先生、ありがとうございます。
こちらMACminiでも、2進モードにして実行すると、
下記のように体感的にはあまり気にならない程度になることを確認しました。
他のBASICプログラムでも同じように、ときどき引っかかるような動きをしていましたが、
2進モードではあまり気にならなくなりなした。
decimal BASIC 0.6.5.2
MAC OS 10.7.5
2.7Ghz Intel Core i7
メモリ 4GB 1333Mhz DDR3
十進BASIC2進モードでの実行結果(ファイル出力)
61 4.00000000008731E-2
62 5.99999999976717E-2
63 4.00000000008731E-2
64 2.99999999988358E-2
65 2.99999999988358E-2
66 2.99999999988358E-2
67 4.00000000008731E-2
68 2.99999999988358E-2
69 4.00000000008731E-2
70 2.99999999988358E-2
71 3.00000000061118E-2
72 3.99999999935972E-2
73 .130000000004657
74 2.99999999988358E-2
75 4.00000000008731E-2
76 2.99999999988358E-2
77 2.99999999988358E-2
78 4.00000000008731E-2
79 2.99999999988358E-2
80 .069999999999709
81 2.99999999988358E-2
82 3.00000000061118E-2
83 2.99999999988358E-2
84 2.99999999988358E-2
85 2.99999999988358E-2
86 2.99999999988358E-2
87 2.99999999988358E-2
88 3.00000000061118E-2
89 5.99999999976717E-2
90 2.99999999988358E-2
91 2.99999999988358E-2
92 4.00000000008731E-2
93 2.99999999988358E-2
94 2.00000000040745E-2
95 2.99999999988358E-2
96 2.99999999988358E-2
97 4.00000000008731E-2
98 2.99999999988358E-2
99 2.99999999988358E-2
100 4.00000000008731E-2
|
|
|
投稿者:白石和夫
投稿日:2017年 1月16日(月)11時36分42秒
|
|
|
原因が描画系にあるのか調べるためにループ内では描画しないようにして実行してみました。
CALL setInitialCondition
CALL drawParticles(100)
DIM times(1 TO 1000)
FOR it=1 TO 1000
LET time0=time
FOR i=1 TO 20
CALL moveParticles
NEXT i
!CALL drawParticles(100)
LET times(it)= TIME-time0
NEXT it
ASK directory dir$
PRINT dir$
OPEN #1: NAME dir$&"/test008.txt"
ERASE #1
FOR it=1 TO 1000
PRINT #1,USING "#### ##.##":it, times(it)
NEXT it
CLOSE #1
END
OS 10.9.5のとき
1 .05
2 .06
3 .08
4 .07
5 .09
6 .07
7 .09
8 .10
9 .10
10 .11
11 .13
12 .43
13 .05
14 .07
15 .04
16 .06
17 .07
18 .09
19 .08
20 .07
21 .09
22 .10
23 .13
24 .13
25 .14
26 .31
27 .04
28 .07
29 .06
30 .05
31 .06
32 .06
33 .07
34 .07
35 .09
36 .08
37 .09
38 .10
39 .14
40 .16
41 .27
42 .12
43 .08
44 .05
45 .06
46 .05
47 .06
48 .06
49 .07
50 .07
(以下、省略)
MAC版十進BASICはグラフィックウィンドウが表示されていると33m秒ごとに再描画します。
グラフックウィンドウが表示されないようにすべての描画命令を削除してから実行すると
1 .03
2 .03
3 .04
4 .03
5 .03
6 .03
7 .03
8 .04
9 .03
10 .03
11 .03
12 .03
13 .04
14 .03
15 .03
16 .03
17 .03
18 .04
19 .03
20 .03
21 .03
22 .04
23 .03
24 .03
25 .03
26 .04
27 .03
28 .03
29 .03
30 .03
31 .04
32 .03
33 .03
34 .03
35 .04
36 .03
37 .03
38 .03
39 .03
40 .04
41 .03
42 .03
43 .03
44 .03
45 .03
46 .03
47 .03
48 .04
49 .03
50 .03
となって、グラフィック画面の再描画に時間がかかり、また、その所要時間が安定しないことがわかります。
OS 10.6.8は
グラッフィク画面表示ありのとき
1 .03
2 .04
3 .04
4 .03
5 .04
6 .03
7 .04
8 .04
9 .03
10 .04
11 .04
12 .03
13 .04
14 .04
15 .03
16 .04
17 .04
18 .03
19 .04
20 .04
21 .03
22 .04
23 .04
24 .03
25 .04
26 .03
27 .04
28 .04
29 .03
30 .04
31 .04
32 .03
33 .04
34 .03
35 .04
36 .03
37 .04
38 .03
39 .03
40 .04
41 .04
42 .03
43 .04
44 .04
45 .03
46 .04
47 .03
48 .04
49 .03
50 .04
グラフィック画面が表示されないとき
1 .03
2 .03
3 .04
4 .03
5 .03
6 .03
7 .03
8 .04
9 .03
10 .03
11 .03
12 .04
13 .03
14 .03
15 .03
16 .03
17 .04
18 .03
19 .03
20 .03
21 .03
22 .04
23 .03
24 .03
25 .03
26 .03
27 .03
28 .03
29 .04
30 .03
31 .03
32 .03
33 .03
34 .03
35 .04
36 .03
37 .03
38 .03
39 .03
40 .03
41 .04
42 .03
43 .03
44 .03
45 .03
46 .04
47 .03
48 .03
49 .03
50 .03
で、ほとんど差がありません。
|
|
|
投稿者:mike
投稿日:2017年 1月16日(月)14時17分9秒
|
|
|
> No.4228[元記事へ]
白石和夫さんへのお返事です。
白石先生、色々とご検討いただき、ありがとうございます。
> グラフィック画面の再描画に時間がかかり、また、その所要時間が安定しないことがわかります。
描画のときになにかのリソースの競合が起こるのでしょうか?
BASIC 0.6.5.2 on macOS においては、プログラム実行中にマウスをクリックすると
実行が一時停止したように見えます。
一方、BASIC778 on windows10においては、プログラム実行中にマウスをクリックしても
実行が中断されません。
BASIC 0.6.5.2 / macOS 10.7.5 のloop所要時間をテキスト画面に出力
70 .15
71 .15
72 .17
73 .17
74 .19
75 .14
76 .15
77 .15
78 .15
79 .15
80 3.57 ****** 画面上でマウスクリックしたままにして、少し間を空けてから解放
81 .3
82 .36
83 .17
84 .17
85 .16
86 .17
87 .17
88 .17
89 .16
90 .17
91 .18
92 .22
93 .23
94 .25
95 .29
96 .4
97 .7
98 .16
99 .17
100 .17
|
|
|
投稿者:mike
投稿日:2017年 1月17日(火)08時24分11秒
|
|
|
> No.4228[元記事へ]
白石和夫さんへのお返事です。
白石先生のまねをして計算moveParticlesと描画drawParticlesの所要時間を同時に計ってみました。
測定結果から次のことが言えそうです。
(1)時間のフラツキは計算部分で起こる。
(2)描画の有無が計算にかかる時間に影響する。
(3)描画にかかる時間は十進モードと2進モードともあまり変わらない。
DIM tCalc(100),tDraw(100)
FOR it=1 TO 100
LET time0 = TIME
FOR i=1 TO 20
CALL moveParticles
NEXT i
LET tCalc(it) = TIME - time0
LET time0 = TIME
CALL drawParticles(100)
LET tDraw(it) = TIME - time0
NEXT it
!
FOR it=1 TO 100
PRINT USING "it=#### tCalc=#.### tDraw=#.###":it,tCalc(it),tDraw(it)
NEXT it
END
-------------------- BASIC 0.6.5.2 / macOS 10.7.5 十進モード
it= 70 tCalc= .490 tDraw= .010 *(>=0.2)
it= 71 tCalc= .230 tDraw= .020 *
it= 72 tCalc= .240 tDraw= .020 *
it= 73 tCalc= .320 tDraw= .020 *
it= 74 tCalc= .350 tDraw= .010 *
it= 75 tCalc= .170 tDraw= .020
it= 76 tCalc= .210 tDraw= .010 *
it= 77 tCalc= .220 tDraw= .010 *
it= 78 tCalc= .250 tDraw= .010 *
it= 79 tCalc= .330 tDraw= .000 *
it= 80 tCalc= .430 tDraw= .010 *
it= 81 tCalc= .150 tDraw= .010
it= 82 tCalc= .140 tDraw= .000
it= 83 tCalc= .140 tDraw= .010
it= 84 tCalc= .130 tDraw= .010
it= 85 tCalc= .140 tDraw= .000
it= 86 tCalc= .140 tDraw= .010
it= 87 tCalc= .140 tDraw= .010
it= 88 tCalc= .130 tDraw= .020
it= 89 tCalc= .140 tDraw= .010
it= 90 tCalc= .140 tDraw= .010
it= 91 tCalc= .160 tDraw= .010
it= 92 tCalc= .170 tDraw= .010
it= 93 tCalc= .140 tDraw= .010
it= 94 tCalc= .130 tDraw= .010
it= 95 tCalc= .130 tDraw= .020
it= 96 tCalc= .130 tDraw= .010
it= 97 tCalc= .130 tDraw= .010
it= 98 tCalc= .140 tDraw= .010
it= 99 tCalc= .130 tDraw= .010
it= 100 tCalc= .140 tDraw= .010
BASIC 0.6.5.2 / macOS 10.7.5 十進モード !CALL drawParticles(100) コメントアウト
it= 70 tCalc= .130 tDraw= .000
it= 71 tCalc= .140 tDraw= .000
it= 72 tCalc= .140 tDraw= .000
it= 73 tCalc= .140 tDraw= .000
it= 74 tCalc= .150 tDraw= .000
it= 75 tCalc= .180 tDraw= .000
it= 76 tCalc= .200 tDraw= .000 *(>=0.2)
it= 77 tCalc= .230 tDraw= .000 *
it= 78 tCalc= .270 tDraw= .000 *
it= 79 tCalc= .140 tDraw= .000
it= 80 tCalc= .130 tDraw= .000
it= 81 tCalc= .140 tDraw= .000
it= 82 tCalc= .140 tDraw= .000
it= 83 tCalc= .160 tDraw= .000
it= 84 tCalc= .170 tDraw= .000
it= 85 tCalc= .200 tDraw= .000 *
it= 86 tCalc= .210 tDraw= .000 *
it= 87 tCalc= .230 tDraw= .000 *
it= 88 tCalc= .130 tDraw= .000
it= 89 tCalc= .130 tDraw= .000
it= 90 tCalc= .140 tDraw= .000
it= 91 tCalc= .140 tDraw= .000
it= 92 tCalc= .140 tDraw= .000
it= 93 tCalc= .140 tDraw= .000
it= 94 tCalc= .170 tDraw= .000
it= 95 tCalc= .190 tDraw= .000
it= 96 tCalc= .190 tDraw= .000
it= 97 tCalc= .130 tDraw= .000
it= 98 tCalc= .140 tDraw= .000
it= 99 tCalc= .130 tDraw= .000
it= 100 tCalc= .140 tDraw= .000
-------------------- BASIC 0.6.5.2 / macOS 10.7.5 2進モード
it= 70 tCalc= .020 tDraw= .020
it= 71 tCalc= .020 tDraw= .010
it= 72 tCalc= .020 tDraw= .010
it= 73 tCalc= .030 tDraw= .000
it= 74 tCalc= .020 tDraw= .020
it= 75 tCalc= .070 tDraw= .010 *(>=0.05)
it= 76 tCalc= .090 tDraw= .010 *
it= 77 tCalc= .040 tDraw= .010
it= 78 tCalc= .020 tDraw= .020
it= 79 tCalc= .020 tDraw= .010
it= 80 tCalc= .020 tDraw= .010
it= 81 tCalc= .020 tDraw= .020
it= 82 tCalc= .020 tDraw= .010
it= 83 tCalc= .100 tDraw= .010 *
it= 84 tCalc= .050 tDraw= .010 *
it= 85 tCalc= .020 tDraw= .010
it= 86 tCalc= .020 tDraw= .010
it= 87 tCalc= .030 tDraw= .010
it= 88 tCalc= .030 tDraw= .010
it= 89 tCalc= .050 tDraw= .010 *
it= 90 tCalc= .020 tDraw= .000
it= 91 tCalc= .020 tDraw= .010
it= 92 tCalc= .020 tDraw= .010
it= 93 tCalc= .020 tDraw= .030
it= 94 tCalc= .020 tDraw= .010
it= 95 tCalc= .030 tDraw= .010
it= 96 tCalc= .020 tDraw= .000
it= 97 tCalc= .020 tDraw= .010
it= 98 tCalc= .020 tDraw= .010
it= 99 tCalc= .020 tDraw= .010
it= 100 tCalc= .020 tDraw= .020
BASIC 0.6.5.2 / macOS 10.7.5 !CALL drawParticles(100) コメントアウト
it= 70 tCalc= .020 tDraw= .000
it= 71 tCalc= .010 tDraw= .000
it= 72 tCalc= .020 tDraw= .000
it= 73 tCalc= .020 tDraw= .000
it= 74 tCalc= .020 tDraw= .000
it= 75 tCalc= .020 tDraw= .000
it= 76 tCalc= .020 tDraw= .000
it= 77 tCalc= .020 tDraw= .000
it= 78 tCalc= .020 tDraw= .000
it= 79 tCalc= .020 tDraw= .000
it= 80 tCalc= .020 tDraw= .000
it= 81 tCalc= .020 tDraw= .000
it= 82 tCalc= .020 tDraw= .000
it= 83 tCalc= .020 tDraw= .000
it= 84 tCalc= .020 tDraw= .000
it= 85 tCalc= .020 tDraw= .000
it= 86 tCalc= .020 tDraw= .000
it= 87 tCalc= .020 tDraw= .000
it= 88 tCalc= .020 tDraw= .000
it= 89 tCalc= .020 tDraw= .000
it= 90 tCalc= .020 tDraw= .000
it= 91 tCalc= .020 tDraw= .000
it= 92 tCalc= .020 tDraw= .000
it= 93 tCalc= .010 tDraw= .000
it= 94 tCalc= .020 tDraw= .000
it= 95 tCalc= .030 tDraw= .000
it= 96 tCalc= .010 tDraw= .000
it= 97 tCalc= .020 tDraw= .000
it= 98 tCalc= .020 tDraw= .000
it= 99 tCalc= .020 tDraw= .000
it= 100 tCalc= .020 tDraw= .000
|
|
|
投稿者:白石 和夫
投稿日:2017年 1月17日(火)12時23分45秒
|
|
|
> (1)時間のフラツキは計算部分で起こる。
> (2)描画の有無が計算にかかる時間に影響する。
> (3)描画にかかる時間は十進モードと2進モードともあまり変わらない。
十進BASICの描画命令は専用のビットマップメモリに書き込みます。
(3)の描画にかかる時間は,十進BASICの描画命令がビットマップに書き込むのに要する時間です。
MAC版十進BASICは,33m秒ごとの割り込みで,ビットマップの内容を画面表示用メモリに転送します。この割り込みは,BASICプログラムの流れと非同期で発生します。この割り込みで起動される処理は,OSが用意した機能を利用します。
ソースコードでは,paintfrm.pasの587行目~にある
procedure TPaintForm.PaintBox1Paint(Sender: TObject);
begin
if not HiddenDrawMode then
begin
{$IFNDEF WINDOWS} SetFPUMask(OriginalCW); {$ENDIF}
PaintBox1.Canvas. Draw(0,0,BitMap1);
{$IFNDEF WINDOWS}SetFPUMask(controlword); {$ENDIF}
end;
end;
procedure TPaintForm.Timer1Timer(Sender: TObject);
begin
{$IFNDEF WINDOWS}
if not hiddenDrawMode then
paintBox1.repaint;
{$ENDIF}
end;
が該当します。タイマー割り込みでTimer1Timerが呼び出され,そこからpaintBox1.repaintを呼び出すと,間接的にPaintBox1Paintが呼び出されて,PaintBox1.Canvas.Draw(0,0,BitMap1)が実行されます。
PaintBox1.Canvas.Drawは,Lazarusのソースを見ないと正確なことはわかりませんが,作業の実体部分はOSに丸投げだと思います。
|
|
|
投稿者:mike
投稿日:2017年 1月17日(火)18時17分46秒
|
|
|
> No.4231[元記事へ]
白石 和夫さんへのお返事です。
白石先生、ご回答、ありがとうございます。
グラフィック命令からの要求によってOS側のサービスのための割り込み、もしくは優先的なスレッドが立ち、
インタープリタ側のスレッドが待たされるようになり、計算が終わるまでの時間がかかるのでしょうか。
BASICインタープリタとOSの境界面は難しく、私にはほとんど理解できません。
ともあれ、mac上のdecimal BASIC 0.6.5.2を使う場合、グラフィック画面の
「ぎくしゃくとした」動きへの対策として、BASICプログラム上では
2進モード(OPTION ARITHMEIC NATIVE)を使うのが有効だとわかりました。
これで本来の目的は半ば達したと考えます。
decimal BASICの次のバージョンで、この辺りの改良がなされることを希望します。
本当にありがとうございました。
|
|
|
投稿者:白石 和夫
投稿日:2017年 1月28日(土)11時48分57秒
|
|
|
> No.4231[元記事へ]
> > (1)時間のフラツキは計算部分で起こる。
> > (2)描画の有無が計算にかかる時間に影響する。
> > (3)描画にかかる時間は十進モードと2進モードともあまり変わらない。
>
> 十進BASICの描画命令は専用のビットマップメモリに書き込みます。
> (3)の描画にかかる時間は,十進BASICの描画命令がビットマップに書き込むのに要する時間です。
> MAC版十進BASICは,33m秒ごとの割り込みで,ビットマップの内容を画面表示用メモリに転送します。この割り込みは,BASICプログラムの流れと非同期で発生します。この割り込みで起動される処理は,OSが用意した機能を利用します。
ビットマップを画面表示するタイミングを50m秒ごととすると安定して動作するようです。
Ver.0.6.6.0では,また,描画命令を実行していないときは,画面の書き換えを行わないようにして計算のみ実行中に計算速度の低下を招かないように変更します。
描画結果の画面転送間隔は,ユーザのホームフォルダに作成される隠しファイル.basic.iniを書き換えて変更できるようにしてあります。[Graphics]セクション中の RepaintInterval=50 の部分です。
|
|
|
投稿者:mike
投稿日:2017年 1月28日(土)13時30分26秒
|
|
|
> No.4242[元記事へ]
白石 和夫さんへのお返事です。
白石先生、素早い対応ありがとうございます。
早速、decimal BASIC0660をダウンロード、インストールさせていただきました。
前回と同じプログラムを使い、ループの所要時間を調べてみました。
下記のように、計算時間のバラツキはほとんどないようです。
実際、見た目にもぎくしゃくとした動きはなくなっていました。
ありがとうございました。
DIM tCalc(100),tDraw(100)
FOR it=1 TO 100
LET time0 = TIME
FOR i=1 TO 20
CALL moveParticles
NEXT i
LET tCalc(it) = TIME - time0
LET time0 = TIME
CALL drawParticles(100)
LET tDraw(it) = TIME - time0
NEXT it
!
FOR it=1 TO 100
PRINT USING "it=#### tCalc=#.### tDraw=#.###":it,tCalc(it),tDraw(it)
NEXT it
END
BASIC 0.6.6.0 / macOS 10.7.5 十進モード
2.7Ghz Intel Core i7
メモリ 4GB 1333Mhz DDR3
it= 61 tCalc= .130 tDraw= .010
it= 62 tCalc= .150 tDraw= .010
it= 63 tCalc= .130 tDraw= .000
it= 64 tCalc= .150 tDraw= .010
it= 65 tCalc= .130 tDraw= .010
it= 66 tCalc= .140 tDraw= .010
it= 67 tCalc= .130 tDraw= .010
it= 68 tCalc= .130 tDraw= .010
it= 69 tCalc= .130 tDraw= .010
it= 70 tCalc= .130 tDraw= .000
it= 71 tCalc= .150 tDraw= .010
it= 72 tCalc= .130 tDraw= .010
it= 73 tCalc= .140 tDraw= .010
it= 74 tCalc= .130 tDraw= .010
it= 75 tCalc= .130 tDraw= .010
it= 76 tCalc= .130 tDraw= .010
it= 77 tCalc= .130 tDraw= .010
it= 78 tCalc= .140 tDraw= .010
it= 79 tCalc= .130 tDraw= .010
it= 80 tCalc= .140 tDraw= .010
it= 81 tCalc= .130 tDraw= .010
it= 82 tCalc= .130 tDraw= .010
it= 83 tCalc= .140 tDraw= .010
it= 84 tCalc= .130 tDraw= .010
it= 85 tCalc= .150 tDraw= .000
it= 86 tCalc= .130 tDraw= .010
it= 87 tCalc= .150 tDraw= .010
it= 88 tCalc= .130 tDraw= .010
it= 89 tCalc= .140 tDraw= .010
it= 90 tCalc= .130 tDraw= .010
it= 91 tCalc= .140 tDraw= .010
it= 92 tCalc= .130 tDraw= .010
it= 93 tCalc= .140 tDraw= .010
it= 94 tCalc= .130 tDraw= .010
it= 95 tCalc= .130 tDraw= .010
it= 96 tCalc= .140 tDraw= .010
it= 97 tCalc= .130 tDraw= .010
it= 98 tCalc= .140 tDraw= .010
it= 99 tCalc= .150 tDraw= .010
it= 100 tCalc= .150 tDraw= .010
|
|
|
戻る