2026年4月2日 星期四

常微方程式之 Runge-Kutta 解法

常微方程式之 Runge-Kutta 解法


曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
2 April 2026


本文專注於引用單一文獻,將一個標準的 FORTRAN 程式,直接改寫成 ABC FORTH 數學計算系統可以執行的程式。改寫的方式幾乎是一列一列對應式的翻譯,執行解得的答案必須與原資料文獻一致,操作的便利性必須符合現今時代潮流,內容則是一個實用的數值分析標準範例。

參考文獻源自:

Brice Carnahan, H. A. Luther, James O. Wilkes, “Applied Numerical Methods”, Chapter 6. Example 6.3. p.367 ~ p.380,

“Forth-order Runge-Kutta method - transient behaviour of a resonant circuit”

本文的主要目的,並不想詳細講解,如何使用計算機設計程式來求解常微方程式?也不想詳細介紹所謂的 Runge-Kutta method ,數值分析專門書籍內可以找到這方面的知識,上述文獻就是非常完整的標準教材。重點集中於強調:如何將任何 FORTRAN 數值分析程式改寫成 ABC FORTH 程式?並展示,大型、複雜、實用的 FORTRAN 數值分析程式很容易改寫,所得的程式,比原 FORTRAN 程式使用起來更為方便。

過去幾十年,普天之下,已不知有多少的專家學者,發表過難以計數卻都非常有用的 FORTRAN 數值分析程式。電腦科技的演進,如果會廢棄這些先聖先賢費盡心血提供出來的研究成果,那就實在是人類的悲哀了,很不幸的是,目前電腦軟體技術的走向,傾向於如此。當年,許多聖賢,公開電腦技術,研究解決數學問題所做的貢獻,都寫成程式、發表成論文,有許多都算得上是精彩的博士論文。但是,現今的電腦環境,幾乎已經不容易再去執行那些有用的程式了。本文單舉一個例子,以 ABC FORTH 數學計算系統實現這種功能。幾十年來的專家學者,在數值分析實務上所做過的貢獻,完全可以輕易的使用 ABC FORTH 數學計算系統令其重現,並且化腐朽為神奇。

本文的主題,大約是理工科系大學三年級以上的學生,才可能遇到的特別數學問題。如果 ABC FORTH 數學計算系統,能夠解決這一等級的數值分析問題,那麼處理一般性的數學計算問題就當然是輕而易舉。已經擁有 ABC FORTH 數學計算系統的使用者,請耐心的讀完本文,以這個實例學會譯寫 FORTRAN 程式,這是本章的宗旨。

常微方程如何用程式來求得解答?

大學中的常微方程課程,教材內容偏重於理論數學,專挑一些理想化了的典型常微方程,例如:線性、常數係數、低階、規則型態的方程式來解釋分析,最重要的是,要能手解求得存在的唯一解答,如此才能讓學生建立常微方程式所代表的觀念,各個理工科系的學生,各有應該專注的不同型態之常微方程,各自深入了解後,就可以應用到後續所學的專業科目上去,能用手解得到的答案,有一個專門術語,稱作解析解(Analytical solution),也就是透過數學理論解釋分析後歸納出來的答案,健全完整,考試要考。

理論上的手解方法,通常都已固定落實了,甚至於都可以寫成公式直接套用。通常的解法,是以固定的演算程序,寫出常微方程之係數尚未確定前的通解(General solution),然後,將已知的起始條件(Initial condition)或邊界條件(Boundary condition)代入通解,最後,確定通解中各項式的未定常數係數,便能獲得代表符合所有條件的特解(Special solution)。

理工科系的學生,要用這些解答來探討他所研究學習的專業科目問題,例如:機械工程系的學生,解得流體力學或熱傳導學的常微方程答案後,就可以了解系統內物理現象變化的趨勢。電機工程系的學生,解得電磁學的常微方程答案後,就容易明白電磁現象的變化。土木工程系的學生,也按同樣的方式,就能夠了解建築結構上力的分佈。化學工程系的學生,用同法來了解化學反應變化。換句話說,工程科技,一定要學常微方程,甚至於偏微方程。

上述僅用一段話,說明求解常微方程的目的,而常微方程通常都是表達自然現象的一種數學式子,能夠被手解的類型所佔比例是非常少的,科學家要大刀闊斧的合理簡化式子後,才能讓原來表示自然現象的常微方程變成可解析,這就是科學上常說的大膽假設。

現實世界中,如果學過了某門工程科學,日後工作時遇到了實際的常微方程,不能每次都用大膽假設法解問題。從事於工程工作是負有責任的,不能全憑假設解問題;較無責任問題的研究工作,有時也不搞假設,因為如果假設不成就會長期沒有進展,研究停滯不前。不能手算獲得解析解的常微方程,不一定就無法可解,科技發展到今天,有了電腦可以協助人類進行快速數學計算,產生了所謂的數值分析技術,以分析問題後採用有依據的數值計算方法,用逼近答案的演算方式求得解答,其結果同樣可以讓人類了解自然現象變化的趨勢而解決科學問題,這樣的解題方法,在學校兩小時的考場內,考試沒辦法考。

求解常微方程的答案時,使用數值分析法與使用手算推演解析解法完全不同,就比較二者在得到答案程序的差異上而言,甚至於可以說是採用完全相反的步驟與方式來獲得解答的。數值分析法一開始,就得使用唯一已經確定的起始條件點或邊界條件點,做為起算基點。古時候,有很多的聖賢應用數學家,例如:本文採用的 Runge-Kutta method 即為其中之一,研究出各種逐步演算推進到下一點的合理方法,寫成數學通式,再翻譯成電腦可以執行的計算程式,藉由電腦的快速演算能力,逐點計算,逐點推進,便可算出此後所有合乎常微方程式所有條件的答案值來。

上述兩種解法所得的答案,最大的不同點,顯示在答案的表示方式上。解析解的答案通常都是可以寫成漂漂亮亮的數學函數的解答,所有工程科系的學生都習慣見到這樣的解答。數值分析解法所獲得的答案,見不到函數表示式,僅只有好幾筆一序列長串印出的數目字,乍看之下,實在不容易看出個所以然來。然而,在應用上,兩種答案意義是一樣的,而且理論上必須相等。這就好比您在查函數表的數值時,您也看不到函數表示式一般,但可以立刻用來解決工程問題。

數值分析技術一定要用到『函數曲線繪圖程式』,利用繪製函數曲線圖形的程式,就可以用圖形來顯示上一段敘述內所得到的數目字解答,將答案繪製成圖後,您就能夠完全了解,數值分析法解得答案的意義了。

以前大學教育裡不太教這種解題技術,當時,電腦的運用沒有那麼方便,情有可原,現在的大學應該要重視這方面的教材,因為,這是一種實際的解題方法,正式的工程問題就得使用。您用得好,工程或研究就做得好,您用不好,工程或研究就做不好。只會解析解的工程科系學生,考試可能可以考得高分,稱得上是秀才。但如果秀才抗拒電腦,拒絕學會數值分析法解工程或研究問題,秀才就會經常沒有用。兩種方法都搞得很好,才能算是人才,我們的社會需要人才而不是秀才。

本文採用的大型例題,要完全研究透徹,須要仔細讀完大約五十頁的英文原文著述,是數值分析教材中一章的份量,若要全譯成漂亮的中文,就得大費周章。我創作 ABC FORTH 系統的主旨不在這裡,我就是希望今後這種文章都不必寫了,只要忠實的告訴您,題材的原始出處,您自行參考,直接取來運用,為後代子孫著想,節約人類寶貴的資源,才是主要宗旨。

這個例題是電路學上,一個分析電阻、電容、電感(RCL)三個電子元件,串聯成一封閉迴路所形成的振盪電路,它可以寫成一個二次的常微方程,來表示電壓隨時間變化的關係,希望能解得具有起始條件後電壓隨時間暫態變化的趨勢解答。


起始條件係假設迴路原為開路狀態,瞬間在電容兩端充以 10 伏特電壓,並立刻將開路改成閉路,則電容兩端電壓隨時間變化的二次常微方程表示式,及這樣的初始條件可以表示式為:

LC*(d(dV/dt)/dt)+RC*(dV/dt)+V=0
V(0) = 10
dV(0)/dt = 0

三個電路元件的物理量假設為:
電容值固定為 C = 2 * 10 ^ -6 farads
電感值固定為 L = 0.5 henries (程式中被表示為 HL )
電阻值可選擇為 R = 0, 100, 1000, 1500 ohms
電容兩端瞬間起始電壓固定為 10 volts
分析時步進間隔值分採 H = 0.00001, 0.0001, 0.001, 0.002, 0.005, 0.01 sec
分析最長時間設定成小於 0.02 秒,亦即 TMAX < 0.02 sec

這個典型的例題是屬於一個可以手算求得解析解的問題,因此,解析解也被用在程式中直接計算,以便將所得結果,與使用 Runge-Kutta method 數值分析解法所得的答案,進行直接比對,驗證數值分析法的合理有效。

詳細的分析與討論,本文不再贅述,有興趣的讀者請自行參考文獻。

這個程式可以被應用到求解所有的常微方程上去,包括高於二次以上的高次常微方程,前處理分析出來的相關通式改寫成程式後,被安排在 MAIN 指令的第 120 及 130 兩列中,想應用於別的常微方程式問題時,就得在這裡替換通式表示式,詳細過程仍請參考文獻後仿照應用。

我可以把這個程式寫得更好、更有效率、更有通用性,但達不到教大家直接改寫 FORTRAN 程式進入 ABC FORTH 系統的效果。因此,我以最大的耐心,逐列翻譯。除了前文曾經提及的輸出、輸入全自創,而不改寫外,整個程式幾乎沒有需要大肆更動之處,簡單的程度,就好比將四川話翻譯成普通話那麼簡單。 FORTRAN 裡面有一個可以多重分支,GO TO (1,2,3,4,5), M 的指令,也很容易依理改寫。程式改寫完畢後的執行結果,當然要與原文列印的結果相同,最多僅能有小數點後面少數幾位數的系統計算性能誤差。這些基本要求, ABC FORTH 都一一實現了,而可以迅速的操作性能,則是 FORTRAN 程式語言所無法辦到的。

微分方程的數值分析解法,其實強調的重點是在試出最恰當的每次步進間隔值,如本文範例程式中的 H ,應該取多少才恰當?取的太大了,逐點推進演算的結果就會算不準。取的太小了,每次可以推進的距離就很小,要算很久、很多點後才有結果。這個現象就如同使用離散(Discrete)表示法,以可隨時間變化的加速度來計算下一個速度值,離散時刻的時間分割至很小時,解答會較準,但要推進很多點後才會有最後希望知道的速度答案。一次就想算得許久時刻後的速度,答案就會很離譜,表示時間間隔值取的太大了,根本不能這樣算。如果重點是這樣,那麼容易操作的數學計算系統就會很有用,可以快速修改、調整、獲得恰當的步進間隔值結果。 ABC FORTH 當然比 FORTRAN 好用多了,這就是我為什麼創作 ABC FORTH 數學計算系統的主因,它可以使運用電腦解決問題的習慣完全改觀。能夠執行數學計算的系統不算甚麼,擁有即時性操作效果的系統就非等閒之輩了。

我以這種方式貢獻給大家的 ABC FORTH 數學計算系統,能使此前出版過的所有數值分析教科書永遠有用,永遠不必被淘汰,因為應用數學的理論部份,是大約 200 年不會過時的,書中的實務範例程式,則可以經由 ABC FORTH 數學計算系統輕易再生,這樣做等於是『化腐朽為神奇』,講求社會道德,減少隨便廢棄有用物質而造福全人類。

我不想浪費時間在電腦編輯系統中,尋找漂亮的數學表示符號編寫這篇文章,所以一些數學表示式,就編寫成意義相同,外觀卻有一點不尋常的格式。

原 FORTRAN 程式去除刊頭文字說明及無用的 FORMAT 內容後,重新打字輸入於此處,數據及執行結果則不再編列於此。改寫完成的 ABC FORTH 對應程式,及其中一套數據輸入後的執行結果,則用電腦系統的可選擇性複製、轉換環境後再貼上的功能,轉置到此處,這是一篇實用教材。


 
   
c     APPLIED NUMERICAL METHODS, EXAMPLE 6.3
c     ELECTRICAL TRANSIENTS USING THE RUNGE-KUTTA METHOD
      IMPLICIT REAL*8( A-H, O-Z)
      INTEGER RUNGE
      DIMMENSION F(2), V(2), IMAGE(1500)
c     …..READ AND PRINT DATA
   1  READ (5,100) R, HL, C, VZERO, H, TMAX, IFREQ, IFPLOT
      WRITE (6,200) R, HL, C, VZERO, H, TMAX, IFREQ, IFPLOT
c     …..INITIALIZE T, V(1), V(2) AND ICOUNT
      T = 0.0
      V(1) = VZERO
      V(2) = 0.0
      ICOUNT = 0
c     …..COMPUTE ALPHSQ AND ALPHA, PRINT HEADINGS
      ALPHSQ = 1./(C*HL) – R* R /(4.0*HL*HL)
      ALPHA = DSQRT (DABX(ALPHSQ))
      RO2L = R/(2.*HL)
      IF ( IFPLOT .NE. 1 ) GO TO 3
        CALL PLOT1( 0, J, 11, 6, 19 )
        CALL PLOT2( IMAGE, TMAX, 0., DABS(VZERO), -DABS(VZERO) )
    3 WRITE (6,201)
c      …..IS CIRCUIT OVER-, CRITICALLY-, OR UNDER-DAMPED
c      …..COMPUTE ANALYTICAL SOLUTION, PRINT AND PLOT
    4  IF (ALPHSQ) 5, 6, 7
    5  TRUV =VZERO*DEXP(-RO2L*T)*((1.+RO2L/ALPHA)*
    1 DEXP(ALPHA*T)+(1.-RO2L/ALPFA)*DEXP(-ALPHA*T))/2.0
      GO TO 8
    6 TRUV =VZERO*DEXP(-RO2L*T)*(1.+RO2L*T)
      GO TO 8
    7 TRUV=VZERO*DEXP(-RO2L*T)*DCOS(ALPHA*T-DATAN(RO2L/ALP
    1 HA))/(ALPHA*DSQRT(C*HL))
    8 IF ( IFPLOT .NE. 1 ) GO TO 10
      CALL PLOT3( 1H*, T, V(1), 1, 8)
   10 WRITE (6,202) T, V(1), TRUV, V(2)
c     …..CALL ON THE FOURTH-ORDER RUNGE-KUTTA FUNCTION
   11 K = RUNGE(2,V, F, T, H )
c     …..WHENEVER K=1, COMPUTE DERIVATIVE VALUES
      IF ( K .NE. 1 ) GO TO 13
      F(1)=V(2)
      F(2)=-R*V(2)/HL –V(1)/(HL*C)
      GO TO 11
c    …..IF T EXCEEDS TMAX, TERMINATE INTEGRATION
   13 IF ( T .LE. TMAX ) GO TO 16
      IF ( IFPLOT .NE. 1 ) GO TO 1
      WRITE ( 6,203)
      CALL PLOT4( 7, 7HVOLTAGE )
      WRITE ( 6,204)
      GO TO 1
   16 ICOUNT=ICOUNT+1
c     …..PRINT RESULTS OR CALL DIRECTLY ON RUNGE
      IF ( ICOUNT .NE. IFREQ ) GO TO 11
      ICOUNT = 0
      GO TO 4
c     …..FORMATS FOR INPUT AND OUTPUT STATEMENTS
100   FORMAT ( …………..)
200   FORMAT (……………)
201   FORMAT (…全略……)
202   FORMAT (……………)
203   FORMAT (……………)
204   FORMAT (……………)
      END

FUNCTION RUNGE( N, Y, F, X, H )
IMPLICIT REAL*8(A-H, O-Z)
REAL*8 Y, F, X, H
INTEGER RUNGE
DIMENSION PHI(50), SAVEY(50), Y(N), F(N)
DATA   M/0/
M=M+1
GO TO (1,2,3,4,5), M
c     …..PASS 1
   1  RUNGE=1
      RETURN
c     …..PASS 2
   2  DO 22 J = 1 , N
      SAVEY(J)=Y(J)
      PHI(J)=F(J)
    22 Y(J)=SAVEY(J)+0.5*H*F(J)
X=X+0.5*H
RUNGE=1
RETURN
c     …..PASS 3
   3  DO 33 J = 1, N
      PHI(J)=PHI(J)+2.0*F(J)
    33 Y(J)=SAVEY(J)+0.5*H*F(J)
RUNGE=1
RETURN
c     …..PASS 4
   4  DO 44 J=1, N
      PHI(J)=PHI(J)+2.0*F(J)
    44 Y(J)=SAVEY(J)+H*F(J)
X=X+0.5*H
RUNGE=1
RUTURN
c     …..PASS 5
   5  DO 55 J = 1, N
  55  Y(J)=SAVEY(J)+(PHI(J)+F(J))*H/6.0
      M=0
      RUNGE=0
      RETURN
      END

改寫完成的 ABC FORTH 完整程式及十群範例輸入數據如下:

\ Runge-Kutta Method for ODE

INTEGER M     INTEGER J     INTEGER RUNGE
INTEGER N
10 ARRAY Y    10 ARRAY F
REAL X        REAL H
50 ARRAY PHI  50 ARRAY SAVEY

: F(RK4)     BASIC
10 REM ***F(RUNGE) = FUNCTION RUNGE( N, Y, F, X, H )
20 LET M = M + 1
30 IF M = 1 THEN 60
40 GOTO 80
50 REM ***PASS 1
60 LET RUNGE = 1
70 GOTO 9999
80 IF M = 2 THEN 110
90 GOTO 180
100 REM ***PASS 2
110 FOR J = 1 TO N
120 LET { SAVEY ( J ) = Y ( J ) }
125 LET { PHI ( J ) = F ( J ) }
130 LET { Y ( J ) = SAVEY ( J ) + 0.5 * H * F ( J ) }
140 NEXT J
150 LET { X = X + 0.5 * H }
160 LET RUNGE = 1
170 GOTO 9999
180 IF M = 3 THEN 210
190 GOTO 270
200 REM ***PASS 3
210 FOR J = 1 TO N
220 LET { PHI ( J ) = PHI ( J ) + 2.0 * F ( J ) }
230 LET { Y ( J ) = SAVEY ( J ) + 0.5 * H * F ( J ) }
240 NEXT J
250 LET RUNGE = 1
260 GOTO 9999
270 IF M = 4 THEN 300
280 GOTO 370
290 REM ***PASS 4
300 FOR J = 1 TO N
310 LET { PHI ( J ) = PHI ( J ) + 2.0 * F ( J ) }
320 LET { Y ( J ) = SAVEY ( J ) + H * F ( J ) }
330 NEXT J
340 LET { X = X + 0.5 * H }
350 LET RUNGE = 1
360 GOTO 9999
370 IF M = 5 THEN 400
380 GOTO 430
390 REM ***PASS 5
400 FOR J = 1 TO N
410 LET { Y ( J ) = SAVEY ( J ) + ( PHI ( J ) + F ( J ) ) * H / 6.0 }
420 NEXT J
430 LET M = 0
440 LET RUNGE = 0
9999 END ;

INTEGER K       INTEGER ICOUNT常微方程式之 Runge-Kutta 解法
INTEGER IFREQ   INTEGER IFPLOT
REAL RT1   REAL RT2      REAL RT3
REAL R     REAL HL       REAL C         REAL VZERO
REAL RO2L  REAL ALPHA   REAL ALPHSQ
REAL TRUY  REAL TMAX

: GROUP1
  {{ R = 100.00  }} {{ HL    =  0.50 }}
  {{ C = 2.0E-6  }} {{ VZERO = 10.00 }}
  {{ H = 0.00001 }} {{ TMAX  = 0.025 }}
  [[ IFREQ =  25 ]] [[ IFPLOT =   0  ]]
;
: GROUP2
  {{ R =    0.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00010 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =  10 ]] [[ IFPLOT =    0 ]]
;
: GROUP3
  {{ R = 1000.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00010 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =  10 ]] [[ IFPLOT =    0 ]]
;
: GROUP4
  {{ R = 1500.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00010 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =  10 ]] [[ IFPLOT =    0 ]]
;
: GROUP5
  {{ R =  100.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00001 }} {{ TMAX  = 0.020 }}
  [[ IFREQ = 100 ]] [[ IFPLOT =    0 ]]
;
: GROUP6
  {{ R =  100.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00010 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =  10 ]] [[ IFPLOT =    0 ]]
;
: GROUP7
  {{ R =  100.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00100 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =   1 ]] [[ IFPLOT =    0 ]]
;
: GROUP8
  {{ R =  100.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00200 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =   1 ]] [[ IFPLOT  =   0 ]]
;
: GROUP9
  {{ R =  100.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.00500 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =   1 ]] [[ IFPLOT =    0 ]]
;
: GROUP10
  {{ R =  100.00 }} {{ HL    =  0.50 }}
  {{ C =  2.0E-6 }} {{ VZERO =  10.0 }}
  {{ H = 0.01000 }} {{ TMAX  = 0.020 }}
  [[ IFREQ =   1 ]] [[ IFPLOT =    0 ]]
;

: PRINT-INPUT-DATA   BASIC
10 REM ***PRINT DATA
20 PRINT "      R = " ; { R }
30 PRINT "     HL = " ; { HL }
40 PRINT "      C = " ; { C }
50 PRINT " VZERO = " ; { VZERO }
60 PRINT "      H = " ; { H }
70 PRINT "  TMAX = " ; { TMAX }
80 PRINT "  IFREQ = " , IFREQ
90 PRINT " IFPLOT = " , IFPLOT
100 END ;

: INIT    BASIC
10 REM ***INITIALIZE X, Y(1), Y(2), AND ICOUNT
20 LET { X = 0 }
30 LET { Y ( 1 ) = VZERO }
40 LET { Y ( 2 ) = 0.0 }
50 LET ICOUNT = 0
60 LET N = 2 
70 END ;

: WRITE(6,201)
\ PRINT HEADINGS
  CR 10 SPACES ." X "      10 SPACES ." CALC. Y "
     10 SPACES ." TRUE Y " 10 SPACES ." CALC. Y' " CR
;

: COMPUTE-CONSTANT   BASIC
10 REM ***COMPUTE ALPHSQ AND ALPHA, PRINT HEADINGS
20 LET { ALPHSQ = 1. / ( C * HL ) - R * R / ( 4.0 * HL * HL ) }
30 LET { ALPHA = SQRT ( ABS ( ALPHSQ ) ) }
40 LET { RO2L = R / ( 2. * HL ) }
50 IF IFPLOT <> 1 THEN 80
60 REM ***CALL PLOT1
70 REM ***CALL PLOT2
80 RUN WRITE(6,201)
90 END ;

: WRITE(6,202)   BASIC
10 REM ***PRINT SOLUTION
20 PRINT { X , Y ( 1 ) , TRUY , Y ( 2 ) }
30 END ;

: DAMPED   BASIC
10 REM ***IS CIRCUIT OVER-, CRITICALLY-, OR UNDER-DAMPED
20 REM ***COMPUTE ANALYTICAL SOLUTION, PRINT OR PLOT
30 IF { ALPHSQ < 0 } THEN 50
40 GOTO 100
50 LET { RT1 = ( 1. + RO2L / ALPHA ) * EXP ( ALPHA * X ) }
60 LET { RT2 = ( 1. - RO2L / ALPHA ) * EXP ( NEGATE ( ALPHA ) * X ) }
70 LET { RT3 = ( RT1 + RT2 ) / 2.0 }
80 LET { TRUY = VZERO * EXP ( NEGATE ( RO2L ) * X ) * RT3 }
90 GOTO 170
100 IF { ALPHSQ = 0 } THEN 120
110 GOTO 140
120 LET { TRUY = VZERO * EXP ( NEGATE ( RO2L ) * X ) * ( 1. + RO2L * X ) }
130 GOTO 170
140 LET { RT1 = COS ( ALPHA * X - ATAN ( RO2L / ALPHA ) ) }
150 LET { RT2 = ALPHA * SQRT ( C * HL ) }
160 LET { TRUY = VZERO * EXP ( NEGATE ( RO2L ) * X ) * RT1 / RT2 }
170 IF IFPLOT <> 1 THEN 190
180 REM ***CALL PLOT3
190 RUN WRITE(6,202)
200 END ;

: CALL-FUNCTION-F(RK4)
  F(RK4)
;

: MAIN   BASIC	\ 執行Runge-Kutta的主要指令
10 RUN GROUP2  \ (1)輸入數據建立了十組,於此處自行選擇更換
20 RUN PRINT-INPUT-DATA
30 RUN INIT
40 RUN COMPUTE-CONSTANT
50 RUN DAMPED
60 REM ***CALL ON THE FOURTH-ORDER RUNGE-KUTTA FUNCTION
70 LET M = 0
80 RUN CALL-FUNCTION-F(RK4)
90 LET K = RUNGE
100 REM ***WHENEVER K=1, COMPUTE DERIVATIVE VALUES
110 IF RUNGE <> 1 THEN 150
120 LET { F ( 1 ) = Y ( 2 ) }
130 LET { F ( 2 ) = NEGATE ( R ) * Y ( 2 ) / HL - Y ( 1 ) / ( HL * C ) }
140 GOTO -80
150 REM *** IF X EXCEEDS TMAX, TEERMINATE INTEGRATION
160 IF { X <= TMAX } THEN 210
170 GOTO 260
\ 180 IF IFPLOT <> 1 THEN -10
\ 190 REM ***WRITE(6,203),CALL PLOT4,WRITE(6,204)
\ 200 GOTO -10
210 LET ICOUNT = ICOUNT + 1
220 REM ***PRINT RESULTS OR CALL DIRECTLY ON RUNGE
230 IF ICOUNT <> IFREQ THEN -70
240 LET ICOUNT = 0
250 GOTO -50
260 PRINT " ***Run next GROUPn by change ( 10 RUN GROUPn )*** "
270 END ;

直接操作ABC FORTH系統,執行MAIN指令,所得結果顯示如下:

MAIN
     R =     0.000000000E-1
    HL =      .5000000000
     C =     2.000000000E-6
 VZERO =    10.00000000
     H =      .0001000000
  TMAX =      .0200000000
 IFREQ =    10
IFPLOT =     0
          X              CALC. Y         TRUE Y              CALC. Y'

   0.000000000E-1      10.00000000     10.00000000          0.000000000E-1
    .0010000000         5.403029671     5.403023059     -8414.704778
    .0020000000        -4.161452687    -4.161468365     -9092.979918
    .0030000000        -9.899919391    -9.899924966     -1411.224448
    .0040000000        -6.536459532    -6.536436209      7568.001143
    .0050000000         2.836581058     2.836621855      9589.251198
    .0060000000         9.601684950     9.601702867      2794.201656
    .0070000000         7.539057071     7.539022543     -6569.818977
    .0080000000        -1.454933809    -1.455000338     -9893.586642
    .0090000000        -9.111266133    -9.111302619     -4121.250371
    .0100000000        -8.390754644    -8.390715291      5440.137662
    .0110000000          .0441656076     .0442569799     9999.894840
    .0120000000         8.438479098     8.438539587      5365.808798
    .0130000000         9.074504988     9.074467815     -4201.568624
    .0140000000         1.367486013     1.367372182     -9906.048042
    .0150000000        -7.596790229    -7.596879129     -6502.966258
    .0160000000        -9.576622425    -9.576594803      2878.902739
    .0170000000        -2.751765848    -2.751633381      9613.924740
    .0180000000         6.603046592     6.603167082      7509.961785
    .0190000000         9.887056797     9.887046182     -1498.614135
***Run next GROUPn by change ( 10 RUN GROUPn )***  ok

執行後所得結果,與原始資料內容比較,毫不遜色。


沒有留言: