The attached file, in which I play around with arrays, using them to solve
systems of linear equations, will help.  It includes a really good function
by Andy Martin.

Russell [EMAIL PROTECTED]
----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, February 03, 2000 6:26 AM
Subject: [REBOL] Multidimensional arrays ...


> Could anyone elaborate on following, please?
>
> ->> ar: array/initial [3 4] copy ""
> == [["" "" "" ""] ["" "" "" ""] ["" "" "" ""]]
> ->>  change ar/1/1 "adfaf"
> == ""
> ->> ar
> == [["adfaf" "adfaf" "adfaf" "adfaf"] ["adfaf" "adfaf" "adfaf" "adfaf"]
> ["adfaf" "adfaf" "adfaf" "adfaf"]]
>
> How to simply write at any multidimensional array position? ar/:i/:j:
> value doesn't work ...
>
> Thanks,
>
> -pekr-
>
>
REBOL []
comment { Includes a demonstration of solving n linear equations for n 
unknowns of the form
                a11*x1 + a12*x2 + ... a1n*xn = b1
                a21*x1 + a22*x2 + ... a2n*x2 = b2
                ...
                an1*x1 + an2*x2 + ... ann*xn = bn

                The solution approach is the congruential-gradient method 
described in 20.3-2(e) of 
                Korn & Korn, "mathematical Handbook for Scientists and 
Engineers", McGraw -Hill, NY NY 1961.
                
                To run the demo, type "test-nxn-its" without the ""'s.  In  
response to subsequent questions, enter the number of unknowns
                and the number of iterations. Except for the effects of 
round-off, n iterations give exact
                solutions. You'll see this for n's of 10 or less. For larger 
n's, such as 20, more
                iterations improve the results.
                
                In the demo, 9 digit random coefficients, aij, are generated in 
the range
                0..1.0, and the same for the "right sides, bj's.  These aij's 
are converted to a symmetric
                (aij = aji) positive definite set and the b's are similarly 
transformed, to yeild the same
                solutions xj's as for the original set of aij's.
                
                The demo displays the transformed coefficients, the transformed 
"right sides",
                the "residuals" (the amounts by which the left sides fail to 
equal the right sides,
                using the solution xj's), and finally, the solution xj's to 9 
decimal places.

                Try n = 20 with 20, 30, 60, and 400 iterations.  You'll see the 
effect of round-off
                errors and how more iterations reduce them.  The 9 place results 
don't change between
                60 and 400 iterations, but the residuals are smaller, so the 
solutions must be improving
                in the non-displayed digits!
                }

comment { Arrays will be taken to be generated by
        z: array [r c]
        which results in a block containing r "row" blocks, each conatining 
c column items.  Array is a REBOL
        function.  The first argument block element is the number of rows, 
the second the number of
        columns.
}

inlzarrayint: func [" Initializes the array with integers 1, 2, ..." a 
/local x 
][
x: 0
foreach row a [
        for col 1 length? row 1 [
                
                poke row col ( x: + x 1)
                ]
        ]
return a
]

pokearyrow: func [a r blk /local ar]
        [ar: copy/deep a
        insert/only remove skip ar (subtract r 1) blk
        return ar
]



display: func [a][
foreach row a [print row]
exit
]

pokeij: func [a i j n][
; print ["i,j= " i j]
        poke (pick a i) j n
        ]

comment { The following definition is a broader application, where the 
path is determined
        by the values in ixlist, which may be integers or path names.  It 
was designed by 
        Andrew Martin.

        It is not used herein.
        }

arPoke: func [ar ixlist x /local temp comd][
         temp: :ar
         comd:  "temp"
        foreach i ixlist [
                either integer? i [comd: rejoin [comd "/" i]]
                                                [comd: rejoin [comd "/" get i]]
                ]
        do bind load rejoin [comd ": " x ] 'comd
        ]

Transpose: func [{ Transposes the rectangular MATRIX, a,} a
        /local r trow row t  s][
        t: array [(length? first a) (length?  a)]
        r: 0
        foreach row a [
                r: + r 1
                for c 1 length? row 1 [
                        pokeij t c r a/:r/:c
                        ]
                ]
        return t
        ]

comment {The following three functions are used to create a matrix equal 
    to the matrix product of Atranspose and A.  But they are erroneous. 
    They are not used further herein; they are commented out by being 
part of this comment.
                        
AAhi: function [a h i ] [s][
        s: 0
        for k 1 length? a 1 [
                s: + s (* a/:h/:k a/:k/:i )
                ]
        ]

AArow: function [a h ][ row ][
        row: make block! []
        for i 1 length? a 1 [
                append row AAhi a h i
                ]
        return row
        ]

AA: function [a][ blk][
        blk: make block! []
        for h 1 length? a 1 [
                insert/only tail blk ( AArow a h)
                ]
        return head blk
        ]

        } ; end of comment

inlzarrand: func [{Initializes the rectangular array a with random      
   "integers" from 1 to n, of the same type as n.}a n][
        random/seed now
        foreach row a [
                for col 1 length? row 1 [
                        poke row col (random n)
                        ]
                ]
        return a
        ]

inlzarrand01: func [a n][
        print [ type? n]
        if = (type? n) integer! [n: to-decimal n]
        random/seed now
        foreach row a [
                for col 1 length? row 1 [
                        poke row col (/ random n n)
                        ]
                ]
        return a
        ]


sumdotprod: func [a b /local dpv sum][
        dpv: make block! []
        sum: 0
        for i 1 length? a 1 [
                append dpv (* (pick a i) (pick b i))
                ]
        foreach elt dpv [
                sum: + sum elt
                ]
        
        return sum
        ]

matprod: func [a b /local ca  ra cb rb  p s ][
        ra: length? a
        rb: ca: length? first a
        comment { ca = no cols of a and also equals num rows of b}
        cb: length? first b
        p: array reduce [ra cb]
        for i 1 ra 1[
                for j 1 cb 1 [
                        s: 0
                        for k 1 ca 1 [
                                s: + s (* a/:i/:k b/:k/:j)
                                ]
                        pokeij p i j s
                        ]
                ]
        return p
        ]

det3: func [a /local d ][
    d: 0
    d: + d (* a/1/1 ((* a/2/2 a/3/3) - (* a/2/3 a/3/2)))
    d: d - (* a/1/2 ((* a/2/1 a/3/3) - (* a/3/1 a/2/3)))
    d: + d (* a/1/3 ((* a/2/1 a/3/2) - (* a/3/1 a/2/2)))
    return d
]

comment { Xi = / det3 cramer a b i det3 a }

cramer: func [a b i /local c][ 
comment { a is nxn matrix of coeffs - b is nx1 matrix of right sides}
        c: copy/deep a  
        c: transpose (pokearyrow (transpose c) i (first transpose b))
        return c
        ]

matsum: func [a b /local s ][
s: copy/deep a
for i 1 length? a 1[
        for j 1 length? first a [
                pokeij s i j (+ a/:i/:j b/:i/:j)
                ]
        ]
return s
]

matsub: func [a b /local s ][
s: copy/deep a
for i 1 length? a 1[
        for j 1 length? first a [
                pokeij s i j ( a/:i/:j - b/:i/:j)
                ]
        ]
return s
]

comment { In the next function, a is nxn symmetric pos definite coeff 
matrix for system of linear equations.
                b is a nx1 col matrix of "right sides".  On output x is nx1 col 
matrix of solutions.
                }               

cgsoln: func [a b /local x  v f n den num1 num2 nod1 nod2 saikxk saikvk]
[
n: length? a
f: array reduce [n 1]
for i 1 n 1 [
        pokeij f i 1 (subtract 0 b/:i/1)
        ]
x: array/initial  reduce [n 1] 0.0
v: copy/deep f
for j 1  (+ n 1) 1      [                ; jth iteration
        den: 0
        for k 1 n 1[
                for h 1 n 1[
                        den: + den (*  a/:k/:h (*  v/:k/1 v/:h/1))
                        ]
                ]
        num1: 0
        for k 1 n 1[
                num1: + num1 (*  f/:k/1  v/:k/1)
                ]
        nod1: / num1 den
        for i 1 n 1 [
                pokeij x i 1 (subtract x/:i/1  (* nod1 v/:i/1))
                ]
        for i 1 n 1 [
                saikvk: 0
                for k 1 n 1[
                        saikvk: + saikvk (* a/:i/:k v/:k/1)
                        ]
                pokeij f i 1 (subtract f/:i/1  (* nod1 saikvk))
                ]
        num2: 0
        for k 1 n 1[
                for h 1 n 1[
                        num2: + num2 (* a/:k/:h (* f/:k/1 v/:h/1))
                        ]
                ]
        nod2: / num2 den
        for i 1 n 1 [
                pokeij v i 1 (subtract f/:i/1 (* nod2 v/:i/1))
                ]
        ] 
display f
return x
]

cgsoln-its: func [a b m /local x  v f n den num1 num2 nod1 nod2 saikxk 
saikvk]
[
n: length? a
f: array reduce [n 1]
for i 1 n 1 [
        pokeij f i 1 (subtract 0 b/:i/1)
        ]
x: array/initial  reduce [n 1] 0.0
v: copy/deep f
for j 1  m 1    [                ; jth iteration
        den: 0
        for k 1 n 1[
                for h 1 n 1[
                        den: + den (*  a/:k/:h (*  v/:k/1 v/:h/1))
                        ]
                ]
        num1: 0
        for k 1 n 1[
                num1: + num1 (*  f/:k/1  v/:k/1)
                ]
        nod1: / num1 den
        for i 1 n 1 [
                pokeij x i 1 (subtract x/:i/1  (* nod1 v/:i/1))
                ]
        for i 1 n 1 [
                saikvk: 0
                for k 1 n 1[
                        saikvk: + saikvk (* a/:i/:k v/:k/1)
                        ]
                pokeij f i 1 (subtract f/:i/1  (* nod1 saikvk))
                ]
        num2: 0
        for k 1 n 1[
                for h 1 n 1[
                        num2: + num2 (* a/:k/:h (* f/:k/1 v/:h/1))
                        ]
                ]
        nod2: / num2 den
        for i 1 n 1 [
                pokeij v i 1 (subtract f/:i/1 (* nod2 v/:i/1))
                ]
        ]
print "Residuals"
display f
Print "Solution"
display x
exit
]

comment { The next function is a demonstration of creating a set of n   
    linear equations in n unknowns with randomized coefficients and then 
    solving them by the congruential gradient method using m iterations.
}

test-nxn-its: func [ /local n m a b at ata atb xs][
n: to-integer ask "Number of unknowns? "
m: to-integer ask "Number of iterations (not less than unknowns)? "
a: array reduce [n n]
b: array reduce [n 1]
a: inlzarrand01 a 1e9
b: inlzarrand01 b 1e9
at: transpose a
ata: matprod at a 
print "SymPosDef-A"
display ata
atb: matprod at b 
print "Right sides"
display atb
cgsoln-its ata atb m
]

Reply via email to