一百個例題 (41 ~ 45)
Ching-Tang Tseng
Hamilton, New Zealand
9 September 2024
\ (41)LineEquation.f \ 使用了=/=符號,因此只適用於V.658以後版本。 (( Theme : Line equation Author : Ching-Tang Tseng, Hamilton, New Zealand Date : 2015-03-20 Reference : None Description : Equation of a line determined by two points y = ax+b a = (y2-y1)/(x2-x1) b = y1-((y2-y1)*x1/(x2-x1)) yi = y1+(xi-x1)*(y2-y1)/(x2-x1) )) 8 Reals X1 Y1 X2 Y2 Xi Yi a b : Reset {{ X1 = 0 }} {{ Y1 = 0 }} {{ X2 = 0 }} {{ Y2 = 0 }} {{ Xi = 0 }} {{ Yi = 0 }} {{ a = 0 }} {{ b = 0 }} ; : QAEnter BASIC 10 RUN PAGE CR 20 PRINT " Equation of a line determined by coordinates of two points. " 30 PRINT " Then, enter a new Xi, correspondent Yi can be computed out. " 40 RUN CR CR 50 PRINT " Enter 1st point coordinates X1 Y1 " 60 InputR X1 , Y1 70 PRINT " Enter 2nd point coordinates X2 Y2 " 80 InputR X2 , Y2 90 END ; : ExceptionTreatment BASIC 10 IF { ( X1 = X2 ) AND ( Y1 = Y2 ) } THEN 80 20 IF { X1 = X2 } THEN 40 30 IF { Y1 = Y2 } THEN 60 40 PRINT { " This is a vertical line. Line Equation: x = " ; X1 } 50 GOTO 90 60 PRINT { " This is a horizontal line. Line Equation: y = " ; Y1 } 70 GOTO 90 80 PRINT " Enter data are the same point, program stopped! " 90 END ; : LineEquation BASIC 10 LET { a = ( Y2 - Y1 ) / ( X2 - X1 ) } 20 LET { b = Y1 - ( ( Y2 - Y1 ) * X1 / ( X2 - X1 ) ) } 30 IF { b >= 0 } THEN 60 40 PRINT CR { " Line Equation: y = " ; a ; " x - " ; abs ( b ) } 50 GOTO 70 60 PRINT CR { " Line Equation: y = " ; a ; " x + " ; b } 70 END ; Integer K : hi BASIC 10 RUN Reset 20 RUN QAEnter 30 IF { ( X1 =/= X2 ) AND ( Y1 =/= Y2 ) } THEN 60 40 RUN ExceptionTreatment 50 GOTO 150 60 RUN LineEquation 70 PRINT " Enter Xi " 80 InputR Xi 90 LET { Yi = Y1 + ( Xi - X1 ) * ( Y2 - Y1 ) / ( X2 - X1 ) } 100 PRINT { " Xi = " ; Xi ; " Yi = " ; Yi } 110 PRINT CR " Repeat(y/Y)? " 120 LET K = KEY 130 RUN K EMIT 140 IF ( K = 89 ) OR ( K = 121 ) THEN -70 150 END ; cr cr .( Usage: hi )
\ (42)LinearLeastSquareCurveFit.f \ 最小平方直線擬合(調適),利用公式直接計算求得答案。 (( Theme : First-Order Least Squares Curve Fitting Author : Ching-Tang Tseng, Hamilton, New Zealand Date : 2015-01-25 Reference : F.R. Ruckdeschel, BASIC Scientific Subroutines Vol.II BYTE/McGraw-Hill, 1980, p.16 Description : This program calculates a linear least squares fit to a given data set. y = a + b x, given (Xi,Yi), i>1, get a, b. i>2, Standard Deviation D as well. Hint: using formula to do the tedious computation. a = ( Sum(Xi)*Sum(Yi))-N*(Sum(Xi*Yi) )/( (Sum(Xi))^2-N*Sum((Xi)^2) ) b = ( Sum(Xi)*Sum(Xi*Yi)-Sum((Xi)^2)*Sum(Yi) )/( (Sum(Xi))^2-N*Sum((Xi)^2) ) D = SQRT ( Sum(Yi-a-b*Xi)/(N-2) ) )) 20 value Size \ Unique setting in this program for maximum matrix Dimension Size ARRAY XX Size ARRAY YY 10 Reals A B D D1 A1 A2 B0 B1 X Y 2 Integers N I : ResetArray BASIC 10 FOR I = 1 TO Size 20 LET { XX ( I ) = 0 } 30 LET { YY ( I ) = 0 } 40 NEXT I 50 END ; : ResetAll ResetArray {{ A1 = 0 }} {{ A2 = 0 }} {{ B0 = 0 }} {{ B1 = 0 }} ; : FixedData [[ N = 11 ]] {{ XX ( 1 ) = 0 }} {{ YY ( 1 ) = 0 }} {{ XX ( 2 ) = 0.157 }} {{ YY ( 2 ) = 0.1563558123 }} {{ XX ( 3 ) = 0.314 }} {{ YY ( 3 ) = 0.3088655201 }} {{ XX ( 4 ) = 0.471 }} {{ YY ( 4 ) = 0.4537776271 }} {{ XX ( 5 ) = 0.628 }} {{ YY ( 5 ) = 0.5875275257 }} {{ XX ( 6 ) = 0.785 }} {{ YY ( 6 ) = 0.7068251811 }} {{ XX ( 7 ) = 0.942 }} {{ YY ( 7 ) = 0.8087360606 }} {{ XX ( 8 ) = 1.099 }} {{ YY ( 8 ) = 0.8907533184 }} {{ XX ( 9 ) = 1.256 }} {{ YY ( 9 ) = 0.9508594605 }} {{ XX ( 10 ) = 1.413 }} {{ YY ( 10 ) = 0.9875759713 }} {{ XX ( 11 ) = 1.550 }} {{ YY ( 11 ) = 0.9997837642 }} ; : Coefficient BASIC 10 FOR I = 1 TO N 20 LET { A1 = A1 + XX ( I ) } 30 LET { A2 = A2 + ( XX ( I ) * XX ( I ) ) } 40 LET { B0 = B0 + YY ( I ) } 50 LET { B1 = B1 + ( YY ( I ) * XX ( I ) ) } 60 NEXT I 70 LET { D = ( A1 * A1 ) - ( I>R ( N ) * A2 ) } 80 LET { A = ( A1 * B1 ) - ( A2 * B0 ) } 90 LET { A = A / D } 100 LET { B = ( A1 * B0 ) - ( I>R ( N ) * B1 ) } 110 LET { B = B / D } 120 END ; : StandardDeviation BASIC 10 LET { D = 0 } 20 FOR I = 1 TO N 30 LET { D1 = YY ( I ) - A - ( B * XX ( I ) ) } 40 LET { D = D + ( D1 * D1 ) } 50 NEXT I 60 LET { D = SQRT ( D / ( I>R ( N ) - 2 ) ) } 70 END ; : Outcome BASIC 10 run CR 20 Print " (1)Input data as following : " 30 for i = 1 to N 40 print i ; { XX ( i ) , YY ( i ) } 50 next i 60 run CR 70 PRINT " (2)Fitted equation is : " 80 IF { B >= 0 } THEN 110 90 PRINT { " y = " ; A ; B ; " x " } 100 GOTO 120 110 PRINT { " y = " ; A ; " + " ; B ; " x " } 120 RUN CR 130 PRINT { " (3)Standard deviation of fit is : " ; D } 140 RUN CR 150 END ; : Once BASIC 10 run Coefficient 20 run StandardDeviation 30 run Outcome 40 end ; : test BASIC 10 RUN ResetAll 20 RUN FixedData 30 RUN Once 40 END ; : QAData ( -- ) BASIC 10 PRINT " How many sets of Xi Yi given data will be input " 20 InputI N 30 RUN CR 40 FOR I = 1 TO N 50 PRINT " Enter X( " ; I ; " ) Y( " ; I ; " ) = " 60 InputR X , Y 70 LET { XX ( I ) = X } :: { YY ( I ) = Y } 80 NEXT I 90 END ; : hi BASIC 10 run ResetAll 20 run QAData 30 run Once 40 end ; : FileData ( -- ) BASIC 10 RUN S" (41-1)Data.f" Get-File 20 RUN GetOneLineData 30 LET N = INT ( BRA ( 1 ) ) 40 FOR I = 1 TO N 50 RUN GetOneLineData 60 LET { XX ( I ) = BRA ( 2 ) } :: { YY ( I ) = BRA ( 3 ) } 70 NEXT I 80 END ; : main ( -- ) BASIC 10 run ResetAll 20 RUN FileData 30 RUN Once 40 END ; page .( Usage: ) cr .( 1. test : for fixed input data ) cr .( 2. hi : for interactive input data ) cr .( 3. main : for data input from file ) cr \S \ (42-1)Data.f 數據檔案的內容 11 \ This line means following are 11 sets Xi Yi data. 1 0 1 \ This line means set 1 (Xi,Yi) are (0,1) 2 0.157 0.9918106 \ This line means set 2 (Xi,Yi) are (0.157,0.9918106) 3 0.314 0.96756368 4 0.471 0.92820596 5 0.628 0.87526015 6 0.785 0.8107458 7 0.942 0.73707522 8 1.099 0.65693061 9 1.256 0.57313037 10 1.413 0.48849118 11 1.57 0.40569572
\ (43-1) Data.f 輸入數據檔案的內容 11 \ This line means following are 11 sets Xi Yi data. 1 0 1 \ This line means set 1 (Xi,Yi) are (0,1) 2 0.157 0.9918106 \ This line means set 2 (Xi,Yi) are (0.157, 0.9918106) 3 0.314 0.96756368 4 0.471 0.92820596 5 0.628 0.87526015 6 0.785 0.8107458 7 0.942 0.73707522 8 1.099 0.65693061 9 1.256 0.57313037 10 1.413 0.48849118 11 1.57 0.40569572 \ (43)2ndOrderLeastSquareCurveFit.f \ 二階最小乘方曲線擬合(調適) \ 利用公式直接計算求得答案。 (( Theme : First-Order Least Squares Curve Fitting Author : Ching-Tang Tseng, Hamilton, New Zealand Date : 2015-01-25 Reference : F.R. Ruckdeschel, BASIC Scientific Subroutines Vol.II BYTE/McGraw-Hill, 1980, p.24 )) \ Size is the unique setting in this program for maximum matrix Dimension 20 value Size Size ARRAY XX Size ARRAY YY 16 Reals A B C D D1 A0 A1 A2 A3 A4 B0 B1 B2 X Y NN 3 Integers M N I : ResetArray BASIC 10 FOR I = 1 TO Size 20 LET { XX ( I ) = 0 } 30 LET { YY ( I ) = 0 } 40 NEXT I 50 END ; : ResetAll ResetArray {{ A0 = 1 }} {{ A1 = 0 }} {{ A2 = 0 }} {{ A3 = 0 }} {{ A4 = 0 }} {{ B0 = 0 }} {{ B1 = 0 }} {{ B2 = 0 }} ; : FixedData [[ N = 11 ]] {{ XX ( 1 ) = 0 }} {{ YY ( 1 ) = 0 }} {{ XX ( 2 ) = 0.157 }} {{ YY ( 2 ) = 0.1563558123 }} {{ XX ( 3 ) = 0.314 }} {{ YY ( 3 ) = 0.3088655201 }} {{ XX ( 4 ) = 0.471 }} {{ YY ( 4 ) = 0.4537776271 }} {{ XX ( 5 ) = 0.628 }} {{ YY ( 5 ) = 0.5875275257 }} {{ XX ( 6 ) = 0.785 }} {{ YY ( 6 ) = 0.7068251811 }} {{ XX ( 7 ) = 0.942 }} {{ YY ( 7 ) = 0.8087360606 }} {{ XX ( 8 ) = 1.099 }} {{ YY ( 8 ) = 0.8907533184 }} {{ XX ( 9 ) = 1.256 }} {{ YY ( 9 ) = 0.9508594605 }} {{ XX ( 10 ) = 1.413 }} {{ YY ( 10 ) = 0.9875759713 }} {{ XX ( 11 ) = 1.550 }} {{ YY ( 11 ) = 0.9997837642 }} ; : Coefficient BASIC 10 FOR M = 1 TO N \ modified from original 0 --> N-1 20 LET { A1 = A1 + XX ( M ) } 30 LET { A2 = A2 + XX ( M ) * XX ( M ) } 40 LET { A3 = A3 + XX ( M ) * XX ( M ) * XX ( M ) } 50 LET { A4 = A4 + XX ( M ) * XX ( M ) * XX ( M ) * XX ( M ) } 60 LET { B0 = B0 + YY ( M ) } 70 LET { B1 = B1 + YY ( M ) * XX ( M ) } 80 LET { B2 = B2 + YY ( M ) * XX ( M ) * XX ( M ) } 90 NEXT M 100 LET { NN = I>R ( N ) } 110 LET { A1 = A1 / NN } 120 LET { A2 = A2 / NN } 130 LET { A3 = A3 / NN } 140 LET { A4 = A4 / NN } 150 LET { B0 = B0 / NN } 160 LET { B1 = B1 / NN } 170 LET { B2 = B2 / NN } 180 LET { D = A0 * ( A2 * A4 - A3 * A3 ) - A1 * ( A1 * A4 - A3 * A2 ) + A2 * ( A1 * A3 - A2 * A2 ) } 190 LET { A = B0 * ( A2 * A4 - A3 * A3 ) + B1 * ( A3 * A2 - A1 * A4 ) + B2 * ( A1 * A3 - A2 * A2 ) } 200 LET { A = A / D } 210 LET { B = B0 * ( A3 * A2 - A1 * A4 ) + B1 * ( A0 * A4 - A2 * A2 ) + B2 * ( A2 * A1 - A0 * A3 ) } 220 LET { B = B / D } 230 LET { C = B0 * ( A1 * A3 - A2 * A2 ) + B1 * ( A1 * A2 - A0 * A3 ) + B2 * ( A0 * A2 - A1 * A1 ) } 240 LET { C = C / D } 250 END ; : StandardDeviation BASIC 10 LET { D = 0 } 20 FOR M = 1 TO N \ modified from original 0 --> N-1 30 LET { D1 = YY ( M ) - A - B * XX ( M ) - C * XX ( M ) * XX ( M ) } 40 LET { D = D + D1 * D1 } 50 NEXT M 60 LET { D = SQRT ( D / ( NN - 3 ) ) } 70 END ; : Outcome BASIC 10 run CR 20 Print " (1)Input data as following : " 30 for i = 1 to N 40 print i ; { XX ( i ) , YY ( i ) } 50 next i 60 run CR 70 PRINT " (2)Fitted equation is : " CR \ smart print 80 run ." y = " A G. 90 if { B >= 0 } then 120 100 run B G. ." x " 110 goto 130 120 run ." + " B G. ." x " 130 if { C >= 0 } then 160 140 run C G. ." x^2 " CR 150 goto 170 160 run ." + " C G. ." x^2 " CR \ lazy print \ 80 PRINT { " y =( " ; A ; " )+( " ; B ; " )x+( " ; C ; " )x^2 " CR } 170 PRINT { " (3)Standard deviation of fit is : " ; D } 180 RUN CR 190 END ; : Once BASIC 10 run Coefficient 20 run StandardDeviation 30 run Outcome 40 end ; : test BASIC 10 RUN ResetAll 20 RUN FixedData 30 RUN Once 40 END ; : QAData ( -- ) BASIC 10 PRINT " How many sets of Xi Yi given data will be input " 20 InputI N 30 RUN CR 40 FOR I = 1 TO N 50 PRINT " Enter X( " ; I ; " ) Y( " ; I ; " ) = " 60 InputR X , Y 70 LET { XX ( I ) = X } :: { YY ( I ) = Y } 80 NEXT I 90 END ; : hi BASIC 10 run ResetAll 20 run QAData 30 run Once 40 end ; : FileData ( -- ) BASIC 10 RUN S" (42-1)Data.f" Get-File 20 RUN GetOneLineData 30 LET N = INT ( BRA ( 1 ) ) 40 FOR I = 1 TO N 50 RUN GetOneLineData 60 LET { XX ( I ) = BRA ( 2 ) } :: { YY ( I ) = BRA ( 3 ) } 70 NEXT I 80 END ; : main ( -- ) BASIC 10 run ResetAll 20 RUN FileData 30 RUN Once 40 END ; page .( Usage: ) cr .( 1. test : for fixed input data ) cr .( 2. hi : for interactive input data ) cr .( 3. main : for data input from file ) cr \S Usage: 1. test : for fixed input data 2. hi : for interactive input data 3. main : for data input from file ok test (1)Input data as following : 1 0.00000E0 0.00000E0 2 .157000 .156356 3 .314000 .308866 4 .471000 .453778 5 .628000 .587528 6 .785000 .706825 7 .942000 .808736 8 1.09900 .890753 9 1.25600 .950859 10 1.41300 .987576 11 1.55000 .999784 (2)Fitted equation is : y = -.016422 + 1.18056 x -.332942 x^2 (3)Standard deviation of fit is : .011879 ok main Fileid is: 1452 387 Bytes are read into the Fadr RAM buffer! (1)Input data as following : 1 0.00000E0 1.00000 2 .157000 .991811 3 .314000 .967564 4 .471000 .928206 5 .628000 .875260 6 .785000 .810746 7 .942000 .737075 8 1.09900 .656931 9 1.25600 .573130 10 1.41300 .488491 11 1.57000 .405696 (2)Fitted equation is : y = 1.01339 -.121698 x -.175080 x^2 (3)Standard deviation of fit is : .011052 ok
\ (44)LUFactorization.f \ ABC FORTH demo code: Matrix LU factorization \ Author: Ching-Tang Tseng, Hamilton, New Zealand \ Date: 2015-03-27 \ Contact: ilikeforth@gmail.com \ Reference:http://www.ma.utexas.edu/CNA/NA2/programs/f77code/CHP4/genlu.f \ Matrix A is input. \ L(Lower triangular matrix)and U{Upper triangular matrix)are output matrices. \ W(Working matrix) used for checking. \ MD is the unique setting in this program for Maximum matrix Dimension. 10 value MD MD MD matrix a MD MD matrix l MD MD matrix u \ Working matrix MD MD matrix W MD (array) t 4 Reals sum sum1 sum2 sum3 5 Integers i j k m n (( : FixedData [[ n = 3 ]] {{ a ( 1 1 ) = 60 }} {{ a ( 1 2 ) = 30 }} {{ a ( 1 3 ) = 20 }} {{ a ( 2 1 ) = 30 }} {{ a ( 2 2 ) = 20 }} {{ a ( 2 3 ) = 15 }} {{ a ( 3 1 ) = 20 }} {{ a ( 3 2 ) = 15 }} {{ a ( 3 3 ) = 12 }} ; : FixedData [[ n = 3 ]] {{ a ( 1 1 ) = 1 }} {{ a ( 1 2 ) = 3 }} {{ a ( 1 3 ) = 5 }} {{ a ( 2 1 ) = 2 }} {{ a ( 2 2 ) = 4 }} {{ a ( 2 3 ) = 7 }} {{ a ( 3 1 ) = 1 }} {{ a ( 3 2 ) = 1 }} {{ a ( 3 3 ) = 0 }} ; )) : FixedData [[ n = 3 ]] {{ a ( 1 1 ) = 2 }} {{ a ( 1 2 ) = 4 }} {{ a ( 1 3 ) = 7 }} {{ a ( 2 1 ) = 1 }} {{ a ( 2 2 ) = 3 }} {{ a ( 2 3 ) = 5 }} {{ a ( 3 1 ) = 1 }} {{ a ( 3 2 ) = 1 }} {{ a ( 3 3 ) = 0 }} ; : ResetAll basic 10 for i = 1 to n 20 for j = 1 to n 30 let { a ( i j ) = 0 } 40 let { l ( i j ) = 0 } 50 let { u ( i i ) = 0 } 60 next j 70 next i 80 for i = 1 to n 90 let t ( i ) = 0 100 next i 110 end ; : Initialize basic 10 for i = 1 to n 20 let { l ( i i ) = 1 } 30 next i 40 let t ( 1 ) = 1 50 let t ( n ) = 1 60 end ; : LU1 basic 10 for k = 1 to n 20 let { sum = a ( k k ) } 30 for m = 1 to k - 1 40 let { sum = sum - l ( k m ) * a ( m k ) } \ u --> a 50 next m 60 if t ( k ) = 1 then 90 70 let { l ( k k ) = sum / a ( k k ) } \ u --> a 80 goto 100 90 let { u ( k k ) = sum / a ( k k ) } \ l --> a 100 next k 110 end ; : LU2 basic 10 for k = 1 to n 20 let { sum1 = a ( k k ) } 30 for m = 1 to k - 1 40 let { sum1 = sum1 - l ( k m ) * u ( m k ) } 50 next m 60 let { u ( k k ) = sum1 / l ( k k ) } 70 for j = k + 1 to n 80 let { sum2 = a ( k j ) } 90 for m = 1 to k - 1 100 let { sum2 = sum2 - l ( k m ) * u ( m j ) } 110 next m 120 let { u ( k j ) = sum2 / l ( k k ) } 130 next j 140 for i = k + 1 to n 150 let { sum3 = a ( i k ) } 160 for m = 1 to k - 1 170 let { sum3 = sum3 - l ( i m ) * u ( m k ) } 180 next m 190 let { l ( i k ) = sum3 / u ( k k ) } 200 next i 210 next k 220 end ; : PrintMatrixW ( -- ) BASIC 10 RUN CR 20 FOR I = 1 TO N 30 FOR J = 1 TO N 40 LET { Sum = W ( I J ) } \ Based on W matrix 40 RUN Sum (F,) \ Right justified printing 50 NEXT J 60 RUN CR 70 NEXT I 80 END ; : TotalAmount ( -- ) MD 1+ DUP * 3 CELLS * ; : MoveAtoW ( -- ) {{ A ( 0 0 ) }} {{ W ( 0 0 ) }} TotalAmount CMOVE ; : MoveLtoW ( -- ) {{ l ( 0 0 ) }} {{ W ( 0 0 ) }} TotalAmount CMOVE ; : MoveUtoW ( -- ) {{ u ( 0 0 ) }} {{ W ( 0 0 ) }} TotalAmount CMOVE ; : l*uToW ( -- ) BASIC \ Square Matrix Multiplication \ W(i,j) = l(i,j) * u(i,j) 10 FOR I = 1 TO N 20 FOR J = 1 TO N 30 LET { W ( I J ) = 0 } 40 FOR K = 1 TO N 50 LET { W ( I J ) = W ( I J ) + l ( I K ) * u ( K J ) } 60 NEXT K 70 NEXT J 80 NEXT I 90 END ; : Checking ( -- ) l*uToW PrintMatrixW ; : Print-alu basic 10 run MoveAToW 20 print " a ( i j ) = " 30 run PrintMatrixW 40 run MoveLToW 50 print " l ( i j ) = " 60 run PrintMatrixW 70 run MoveUToW 80 print " u ( i j ) = " 90 run PrintMatrixW 100 end ; : test page ResetAll FixedData Initialize cr ." *** Before *** " cr Print-alu LU1 LU2 cr ." *** After *** " cr Print-alu cr ." *** Checking *** " cr cr ." W ( i j ) = l ( i j ) * u ( i j ) = a ( i j ) " Checking cr ." *** Finished *** " cr ; test \ ***** The end of program ***** \S (1)Computer output: *** Before *** a ( i j ) = 60.0000 30.0000 20.0000 30.0000 20.0000 15.0000 20.0000 15.0000 12.0000 l ( i j ) = 1.00000 0.00000E0 0.00000E0 0.00000E0 1.00000 0.00000E0 0.00000E0 0.00000E0 1.00000 u ( i j ) = 0.00000E0 0.00000E0 0.00000E0 0.00000E0 0.00000E0 0.00000E0 0.00000E0 0.00000E0 0.00000E0 *** After *** a ( i j ) = 60.0000 30.0000 20.0000 30.0000 20.0000 15.0000 20.0000 15.0000 12.0000 l ( i j ) = 1.00000 0.00000E0 0.00000E0 .500000 1.00000 0.00000E0 .333333 1.00000 1.00000 u ( i j ) = 60.0000 30.0000 20.0000 0.00000E0 5.00000 5.00000 0.00000E0 0.00000E0 .333333 *** Checking *** W ( i j ) = l ( i j ) * u ( i j ) = a ( i j ) 60.0000 30.0000 20.0000 30.0000 20.0000 15.0000 20.0000 15.0000 12.0000 *** Finished *** ok (2)References:(with Tags for bug fixes) Website: http://www.ma.utexas.edu/CNA/NA2/programs/f77code/CHP4/genlu.f c c Numerical Analysis: c Mathematics of Scientific Computing c Third Edition c D.R. Kincaid, E.W. Cheney c Brooks/Cole Publ., 2002 c Copyright (c) 1996 c c Section 4.2 c c Example of general LU-factorization c c c file: genlu.f c parameter (n=3) dimension a(n,n),l(n,n),u(n,n) real l logical t(n) data (a(1,j),j=1,n) / 60.0,30.0,20.0/ data (a(2,j),j=1,n) / 30.0,20.0,15.0/ data (a(3,j),j=1,n) / 20.0,15.0,12.0/ data l(1,1),u(2,2),l(3,3) /6.0,2.0,4.0/ --- meaningless data data (t(i),i=1,n) /.true.,.false.,.true./ modified to /1.0,1.0,1.0/ c print * print *,' General LU-factorization example' print *,' Section 4.2, Kincaid-Cheney' print * c do 3 k=1,n sum = a(k,k) do 2 m=1,k-1 sum = sum - l(k,m)*u(m,k) ---Error, u(m,k) modified to a(m,k) 2 continue if (t(k)) then u(k,k) = sum/l(k,k) ---Error, l(k,k) modified to a(k,k) else l(k,k) = sum/u(k,k) ---Error, u(k,k) modified to a(k,k) endif 3 continue c do 9 k=1,n sum1 = a(k,k) do 4 m=1,k-1 sum1 = sum1 - l(k,m)*u(m,k) 4 continue u(k,k) = sum1/l(k,k) do 6 j=k+1,n sum2 = a(k,j) do 5 m=1,k-1 sum2 = sum2 - l(k,m)*u(m,j) 5 continue u(k,j) = sum2/l(k,k) 6 continue do 8 i=k+1,n sum3 = a(i,k) do 7 m=1,k-1 sum3 = sum3 - l(i,m)*u(m,k) 7 continue l(i,k) = sum3/u(k,k) 8 continue 9 continue c do 11 i=1,n do 10 j=1,n print 12,i,j,l(i,j),i,j,u(i,j) 10 continue 11 continue c 12 format (1x,'l(',i2,',',i2,') =',e13.6,7x, + 'u(',i2,',',i2,') =',e13.6) stop end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \ (44-1)PLUFactorization.f \ ABC FORTH demo code: Matrix PLU factorization \ Author: Ching-Tang Tseng, Hamilton, New Zealand \ Date: 2015-03-30 \ Contact: ilikeforth@gmail.com \ Reference: \ (1)http://www.ma.utexas.edu/CNA/NA2/programs/f77code/CHP4/genlu.f \ (2)Rosettacode website as well. \ Description: \ Matrix a is an input raw data matrix. \ (1)l(Lower triangular matrix) and \ (2)u{Upper triangular matrix) and \ (3)p(Pivot matrix) are output matrices. \ UU, VV, WW(Working matrix) are used for checking. \ MD is the unique setting in this program for Maximum matrix Dimension. 10 value MD MD MD matrix a MD MD matrix l MD MD matrix u MD MD matrix p \ All raw data of input matrix a is stored in matrix q for the checking at last. MD MD matrix q \ Working matrices for multiplication using MD MD matrix UU MD MD matrix VV MD MD matrix WW MD (array) t 4 Reals sum sum1 sum2 sum3 5 Integers i j k m n (( : FixedData [[ n = 3 ]] {{ a ( 1 1 ) = 60 }} {{ a ( 1 2 ) = 30 }} {{ a ( 1 3 ) = 20 }} {{ a ( 2 1 ) = 30 }} {{ a ( 2 2 ) = 20 }} {{ a ( 2 3 ) = 15 }} {{ a ( 3 1 ) = 20 }} {{ a ( 3 2 ) = 15 }} {{ a ( 3 3 ) = 12 }} ; )) : FixedData [[ n = 4 ]] {{ a ( 1 1 ) = 11 }} {{ a ( 1 2 ) = 9 }} {{ a ( 1 3 ) = 24 }} {{ a ( 1 4 ) = 2 }} {{ a ( 2 1 ) = 1 }} {{ a ( 2 2 ) = 5 }} {{ a ( 2 3 ) = 2 }} {{ a ( 2 4 ) = 6 }} {{ a ( 3 1 ) = 3 }} {{ a ( 3 2 ) = 17 }} {{ a ( 3 3 ) = 18 }} {{ a ( 3 4 ) = 1 }} {{ a ( 4 1 ) = 2 }} {{ a ( 4 2 ) = 5 }} {{ a ( 4 3 ) = 7 }} {{ a ( 4 4 ) = 1 }} ; : ResetAll basic 10 for i = 1 to n 20 for j = 1 to n 30 let { a ( i j ) = 0 } 40 let { l ( i j ) = 0 } 50 let { u ( i j ) = 0 } 60 let { p ( i j ) = 0 } 70 next j 80 next i 90 for i = 1 to n 100 let t ( i ) = 0 110 next i 120 end ; \ l and p are unit matrices at beginning. : Initialize basic 10 for i = 1 to n 20 let { l ( i i ) = 1 } 30 let { p ( i i ) = 1 } 40 next i 50 let t ( 1 ) = 1 60 let t ( n ) = 1 70 end ; \ Pivot computes out a pivot matrix integer r : Pivot basic 10 for i = 1 to n 20 let { sum = a ( i i ) } 30 let r = i 40 for j = i to n 50 if { a ( j i ) > sum } then 70 60 goto 90 70 let { sum = a ( j i ) } 80 let r = j 90 next j 100 if i =/= r then 120 110 goto 170 120 for j = 1 to n 130 let { sum1 = p ( i j ) } 140 let { p ( i j ) = p ( r j ) } 150 let { p ( r j ) = sum1 } 160 next j 170 next i 180 end ; : LU1 basic 10 for k = 1 to n 20 let { sum = a ( k k ) } 30 for m = 1 to k - 1 40 let { sum = sum - l ( k m ) * a ( m k ) } \ u(m,k) --> a(m,k) 50 next m 60 if t ( k ) = 1 then 90 70 let { l ( k k ) = sum / a ( k k ) } \ u(k,k) --> a(k,k) 80 goto 100 90 let { u ( k k ) = sum / a ( k k ) } \ l(k,k) --> a(k,k) 100 next k 110 end ; : LU2 basic 10 for k = 1 to n 20 let { sum1 = a ( k k ) } 30 for m = 1 to k - 1 40 let { sum1 = sum1 - l ( k m ) * u ( m k ) } 50 next m 60 let { u ( k k ) = sum1 / l ( k k ) } 70 for j = k + 1 to n 80 let { sum2 = a ( k j ) } 90 for m = 1 to k - 1 100 let { sum2 = sum2 - l ( k m ) * u ( m j ) } 110 next m 120 let { u ( k j ) = sum2 / l ( k k ) } 130 next j 140 for i = k + 1 to n 150 let { sum3 = a ( i k ) } 160 for m = 1 to k - 1 170 let { sum3 = sum3 - l ( i m ) * u ( m k ) } 180 next m 190 let { l ( i k ) = sum3 / u ( k k ) } 200 next i 210 next k 220 end ; \ All ready to print out matrices are based on WW matrix : PrintWW ( -- ) BASIC 10 RUN CR 20 FOR I = 1 TO N 30 FOR J = 1 TO N 40 LET { Sum = WW ( I J ) } 40 RUN Sum (F,) \ Right justified printing 50 NEXT J 60 RUN CR 70 NEXT I 80 END ; : TotalAmount ( -- ) MD 1+ DUP * 3 CELLS * ; : MatrixCopy ( addr addr -- ) TotalAmount CMOVE ; : CopyatoWW ( -- ) {{ a ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyltoWW ( -- ) {{ l ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyutoWW ( -- ) {{ u ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopypToWW {{ p ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyqToWW {{ q ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyaToQ {{ a ( 0 0 ) }} {{ q ( 0 0 ) }} MatrixCopy ; : CopypToUU {{ p ( 0 0 ) }} {{ UU ( 0 0 ) }} MatrixCopy ; : CopyaToVV {{ A ( 0 0 ) }} {{ VV ( 0 0 ) }} MatrixCopy ; : CopyWWToA {{ WW ( 0 0 ) }} {{ A ( 0 0 ) }} MatrixCopy ; : CopylToUU {{ l ( 0 0 ) }} {{ UU ( 0 0 ) }} MatrixCopy ; : CopyuToVV {{ u ( 0 0 ) }} {{ VV ( 0 0 ) }} MatrixCopy ; \ Matrix Multiplication \ WW(i,j) = UU(i,j) * VV(i,j) \ WW = UU * VV : Matrix* ( -- ) BASIC 10 FOR I = 1 TO N 20 FOR J = 1 TO N 30 LET { WW ( I J ) = 0 } 40 FOR K = 1 TO N 50 LET { WW ( I J ) = WW ( I J ) + UU ( I K ) * VV ( K J ) } 60 NEXT K 70 NEXT J 80 NEXT I 90 END ; : Print-alup basic 10 run CopyAToWW 20 print " a ( i j ) = " 30 run PrintWW 40 run CopyLToWW 50 print " l ( i j ) = " 60 run PrintWW 70 run CopyUToWW 80 print " u ( i j ) = " 90 run PrintWW \ Both of the following code formats are the same meaning. \ 100 run CopyptoWW 100 run address-of p ( 0 0 ) fmatrix address-of WW ( 0 0 ) fmatrix MatrixCopy 110 print " p ( i j ) = " 120 run PrintWW 130 end ; : test page ResetAll FixedData Initialize cr ." *** Before *** " cr Print-alup Copyatoq pivot CopyptoUU CopyatoVV matrix* CopyWWtoa cr ." *** After pivot *** " cr Print-alup LU1 LU2 cr ." *** After Factorization *** " cr Print-alup cr ." *** Checking *** " cr cr ." a ( i j ) = " CopyqtoWW PrintWW cr ." p ( i j ) * a ( i j ) = " CopyatoWW PrintWW cr ." l ( i j ) * u ( i j ) = " CopyltoUU CopyutoVV Matrix* PrintWW cr ." *** Finished *** " cr ; test \ ***** The end of program ***** \S References: Rosettacode website DEF PROCpivot(a(), RETURN p()) LOCAL i%, j%, m%, n%, r% : n% = DIM(a(),2) DIM p(n%,n%) : FOR i% = 0 TO n% : p(i%,i%) = 1 : NEXT FOR i% = 0 TO n% m% = a(i%,i%) r% = i% FOR j% = i% TO n% IF a(j%,i%) > m% m% = a(j%,i%) : r% = j% NEXT IF i%<>r% THEN FOR j% = 0 TO n% : SWAP p(i%,j%),p(r%,j%) : NEXT ENDIF NEXT i% ENDPROC \\\\\\\\\\\\\\\\\\\\\\\\ \ (44-1)PLUFileIO.f \ ABC FORTH demo code: Matrix PLU factorization \ Author: Ching-Tang Tseng, Hamilton, New Zealand \ Date: 2015-03-30 \ Contact: ilikeforth@gmail.com \ Reference: \ (1)http://www.ma.utexas.edu/CNA/NA2/programs/f77code/CHP4/genlu.f \ (2)Rosettacode website as well. \ Description: \ Matrix a is an input raw data matrix. \ (1)l(Lower triangular matrix) and \ (2)u{Upper triangular matrix) and \ (3)p(Pivot matrix) are output matrices. \ UU, VV, WW(Working matrix) are used for checking. \ MD is the unique setting in this program for Maximum matrix Dimension. 10 value MD MD MD matrix a MD MD matrix l MD MD matrix u MD MD matrix p \ All raw data of input matrix a is stored in matrix q for the checking at last. MD MD matrix q \ Working matrices, for multiplication using MD MD matrix UU MD MD matrix VV MD MD matrix WW MD (array) t 4 Reals sum sum1 sum2 sum3 6 Integers i j k m n j+1 : MakeAPseudoFile S" 4" firstline \ Leading number marks the line order. S" 1 11 9 24 2" nextline S" 2 1 5 2 6" nextline S" 3 3 17 18 1" nextline S" 4 2 5 7 1" nextline S>FileBuffer ; : ReadData ( -- ) BASIC 10 RUN MakeAPseudoFile 20 RUN GetOneLineData 30 LET N = INT ( BRA ( 1 ) ) 40 FOR i = 1 TO N 50 RUN GetOneLineData 60 FOR j = 1 TO N 70 let j+1 = j + 1 \ Ignore all BRA(1) 80 LET { A ( i j ) = BRA ( j+1 ) } 90 NEXT j 100 NEXT i 110 END ; (( : FixedData [[ n = 3 ]] {{ a ( 1 1 ) = 60 }} {{ a ( 1 2 ) = 30 }} {{ a ( 1 3 ) = 20 }} {{ a ( 2 1 ) = 30 }} {{ a ( 2 2 ) = 20 }} {{ a ( 2 3 ) = 15 }} {{ a ( 3 1 ) = 20 }} {{ a ( 3 2 ) = 15 }} {{ a ( 3 3 ) = 12 }} ; : FixedData [[ n = 4 ]] {{ a ( 1 1 ) = 11 }} {{ a ( 1 2 ) = 9 }} {{ a ( 1 3 ) = 24 }} {{ a ( 1 4 ) = 2 }} {{ a ( 2 1 ) = 1 }} {{ a ( 2 2 ) = 5 }} {{ a ( 2 3 ) = 2 }} {{ a ( 2 4 ) = 6 }} {{ a ( 3 1 ) = 3 }} {{ a ( 3 2 ) = 17 }} {{ a ( 3 3 ) = 18 }} {{ a ( 3 4 ) = 1 }} {{ a ( 4 1 ) = 2 }} {{ a ( 4 2 ) = 5 }} {{ a ( 4 3 ) = 7 }} {{ a ( 4 4 ) = 1 }} ; )) : ResetAll basic 10 for i = 1 to n 20 for j = 1 to n 30 let { a ( i j ) = 0 } 40 let { l ( i j ) = 0 } 50 let { u ( i j ) = 0 } 60 let { p ( i j ) = 0 } 70 next j 80 next i 90 for i = 1 to n 100 let t ( i ) = 0 110 next i 120 end ; \ l and p are unit matrices at beginning. : Initialize basic 10 for i = 1 to n 20 let { l ( i i ) = 1 } 30 let { p ( i i ) = 1 } 40 next i 50 let t ( 1 ) = 1 60 let t ( n ) = 1 70 end ; \ Pivot computes out a pivot matrix integer r : Pivot basic 10 for i = 1 to n 20 let { sum = a ( i i ) } 30 let r = i 40 for j = i to n 50 if { a ( j i ) > sum } then 70 60 goto 90 70 let { sum = a ( j i ) } 80 let r = j 90 next j 100 if i =/= r then 120 110 goto 170 120 for j = 1 to n 130 let { sum1 = p ( i j ) } 140 let { p ( i j ) = p ( r j ) } 150 let { p ( r j ) = sum1 } 160 next j 170 next i 180 end ; : LU1 basic 10 for k = 1 to n 20 let { sum = a ( k k ) } 30 for m = 1 to k - 1 40 let { sum = sum - l ( k m ) * a ( m k ) } \ u(m,k) --> a(m,k) 50 next m 60 if t ( k ) = 1 then 90 70 let { l ( k k ) = sum / a ( k k ) } \ u(k,k) --> a(k,k) 80 goto 100 90 let { u ( k k ) = sum / a ( k k ) } \ l(k,k) --> a(k,k) 100 next k 110 end ; : LU2 basic 10 for k = 1 to n 20 let { sum1 = a ( k k ) } 30 for m = 1 to k - 1 40 let { sum1 = sum1 - l ( k m ) * u ( m k ) } 50 next m 60 let { u ( k k ) = sum1 / l ( k k ) } 70 for j = k + 1 to n 80 let { sum2 = a ( k j ) } 90 for m = 1 to k - 1 100 let { sum2 = sum2 - l ( k m ) * u ( m j ) } 110 next m 120 let { u ( k j ) = sum2 / l ( k k ) } 130 next j 140 for i = k + 1 to n 150 let { sum3 = a ( i k ) } 160 for m = 1 to k - 1 170 let { sum3 = sum3 - l ( i m ) * u ( m k ) } 180 next m 190 let { l ( i k ) = sum3 / u ( k k ) } 200 next i 210 next k 220 end ; \ All ready to print out matrices are based on WW matrix : PrintWW ( -- ) BASIC 10 RUN CR 20 FOR I = 1 TO N 30 FOR J = 1 TO N 40 LET { Sum = WW ( I J ) } 40 RUN Sum (F,) \ Right justified printing 50 NEXT J 60 RUN CR 70 NEXT I 80 END ; : TotalAmount ( -- ) MD 1+ DUP * 3 CELLS * ; : MatrixCopy ( addr addr -- ) TotalAmount CMOVE ; : CopyatoWW ( -- ) {{ a ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyltoWW ( -- ) {{ l ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyutoWW ( -- ) {{ u ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopypToWW {{ p ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyqToWW {{ q ( 0 0 ) }} {{ WW ( 0 0 ) }} MatrixCopy ; : CopyaToQ {{ a ( 0 0 ) }} {{ q ( 0 0 ) }} MatrixCopy ; : CopypToUU {{ p ( 0 0 ) }} {{ UU ( 0 0 ) }} MatrixCopy ; : CopyaToVV {{ A ( 0 0 ) }} {{ VV ( 0 0 ) }} MatrixCopy ; : CopyWWToA {{ WW ( 0 0 ) }} {{ A ( 0 0 ) }} MatrixCopy ; : CopylToUU {{ l ( 0 0 ) }} {{ UU ( 0 0 ) }} MatrixCopy ; : CopyuToVV {{ u ( 0 0 ) }} {{ VV ( 0 0 ) }} MatrixCopy ; \ Matrix Multiplication \ WW(i,j) = UU(i,j) * VV(i,j) \ WW = UU * VV : Matrix* ( -- ) BASIC 10 FOR I = 1 TO N 20 FOR J = 1 TO N 30 LET { WW ( I J ) = 0 } 40 FOR K = 1 TO N 50 LET { WW ( I J ) = WW ( I J ) + UU ( I K ) * VV ( K J ) } 60 NEXT K 70 NEXT J 80 NEXT I 90 END ; : Print-alup basic 10 run CopyAToWW 20 print " a ( i j ) = " 30 run PrintWW 40 run CopyLToWW 50 print " l ( i j ) = " 60 run PrintWW 70 run CopyUToWW 80 print " u ( i j ) = " 90 run PrintWW \ Both of the following formats are the same meaning. \ 100 run CopyptoWW 100 run address-of p ( 0 0 ) fmatrix address-of WW ( 0 0 ) fmatrix MatrixCopy 110 print " p ( i j ) = " 120 run PrintWW 130 end ; : test \ page ResetAll FixedData Initialize page ResetAll ReadData Initialize cr ." *** Before *** " cr Print-alup Copyatoq pivot CopyptoUU CopyatoVV matrix* CopyWWtoa cr ." *** After pivot *** " cr Print-alup LU1 LU2 cr ." *** After Factorization *** " cr Print-alup cr ." *** Checking *** " cr cr ." a ( i j ) = " CopyqtoWW PrintWW cr ." p ( i j ) * a ( i j ) = " CopyatoWW PrintWW cr ." l ( i j ) * u ( i j ) = " CopyltoUU CopyutoVV Matrix* PrintWW cr ." *** Finished *** " cr ; test \ ***** The end of program ***** \S References: Rosettacode website DEF PROCpivot(a(), RETURN p()) LOCAL i%, j%, m%, n%, r% : n% = DIM(a(),2) DIM p(n%,n%) : FOR i% = 0 TO n% : p(i%,i%) = 1 : NEXT FOR i% = 0 TO n% m% = a(i%,i%) r% = i% FOR j% = i% TO n% IF a(j%,i%) > m% m% = a(j%,i%) : r% = j% NEXT IF i% <> r% THEN FOR j% = 0 TO n% : SWAP p(i%,j%),p(r%,j%) : NEXT ENDIF NEXT i% ENDPROC
\ (45)MakeAPseudoFile.f \ ABC FORTH demo code: Make a pseudo file to simplify data input code. \ Author: Ching-Tang Tseng, Hamilton, New Zealand \ Date: 2015-03-30 \ Contact: ilikeforth@gmail.com : FirstLine ( adr len -- ) fadr Fsize 0 FILL Fadr to Fptr DUP +to Fptr Fadr swap cmove 13 Fptr c! 1 +to Fptr 10 Fptr c! 1 +to Fptr ; : NextLine ( adr len -- ) DUP >R Fptr SWAP CMOVE R> +to Fptr 13 Fptr c! 1 +to Fptr 10 Fptr c! 1 +to Fptr ; : S>FileBuffer ( -- ) 26 Fptr c! 1 +to Fptr 0 Fptr c! 1 +to Fptr Fptr Fadr - to Flen Fadr to Fptr Flen to frem ; \ 此套功能建進 V.659 系統永久使用,增加上列三個指令。 \S Usage: fload (45)MakeAPseudoFile.f : MakeAPseudoFile S" 4" firstline \ Leading number marks the line order S" 1 11 9 24 2" nextline S" 2 1 5 2 6" nextline S" 3 3 17 18 1" nextline S" 4 2 5 7 1" nextline S>FileBuffer ; : ReadData ( -- ) BASIC 10 RUN MakeAPseudoFile 20 RUN GetOneLineData 30 LET N = INT ( BRA ( 1 ) ) 40 FOR i = 1 TO N 50 RUN GetOneLineData 60 FOR j = 1 TO N 70 let j+1 = j + 1 \ Ignore all BRA(1) 80 LET { A ( i j ) = BRA ( j+1 ) } 90 NEXT j 100 NEXT i 110 END ; : check MakeAPseudoFile cr Fadr Flen type cr ;
沒有留言:
張貼留言