一百個例題 (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
;
沒有留言:
張貼留言