[GOODIE] Matrix-raok
Richard A. O'Keefe
ok at cs.otago.ac.nz
Mon Nov 25 00:06:16 UTC 2002
Bert Freudenberg <bert at isg.cs.uni-magdeburg.de>
asked how my Matrix class (described by me as basically a minor cleanup
of Array2D) compares with Croquet's Matrix class.
I couldn't even print the Croquet manual (the first page came out;
what Acrobat Reader did with the rest I cannot imagine) and so have
not looked at Croquet. I can only reply based on the specific
examples in Bert Freudenberg's message.
"Create a new array"
a := Matrix[3, 3] fill: #(1 2 3 4 5 6 7 8 9).
Not possible in plain Squeak syntax.
It is not clear whether filling goes by rows or columns,
so I rejected such an ambiguous operation from my design.
a := Matrix rows: 3 columns: 3 tabulate: [:r :c | (r-1)*3+c]
if filling goes by rows, or
a := Matrix rows: 3 columns: 3 tabulate: [:r :c | (c-1)*3+r]
if filling goes by columns.
"Access individual elements"
a[1,2].
a[2,1].
Not possible in plain Squeak syntax.
a at: 1 at: 2
a at: 2 at: 1
"Assign individual elements"
a[3,1] := 42.
a[1,3] := 21.
Not possible in plain Squeak syntax.
a at: 3 at: 1 put: 42
a at: 1 at: 3 put: 21
"Access vectors"
a[1].
a[1,#all].
a[#all,1].
I surmise that these mean "row 1", "row 1", and "column 1" respectively.
a atRow: 1
a atColumn: 1
Names "rowAt:" "columnAt:" were considered, but to me
"a atRow: i put: v" reads better than "a rowAt: i put: v".
"Assign vectors"
a[1] := #(-1 -2 -3). a.
a[1,#all] := #(-3 -4 -5). a.
a[#all,1] := #(-6 -7 -8). a.
Not possible in plain Squeak syntax.
a atRow: 1 put: #(-1 -2 -3). a.
a atRow: 1 put: #(-3 -4 -5). a.
a atColumn: 1 put: #(-6 -7 -8). a.
I am in some doubt whether they should use ... put: or ... putAll: .
"Access sub-arrays"
a[(1 to: 2),(1 to: 2)].
a[(2 to: 3),(2 to: 3)].
This I had not bothered to implement, not having had a need for it.
A new version will be on its way soon supporting
a atRows: 1 to: 2 atColumns: 1 to: 2
a atRows: 2 to: 3 atColumns: 2 to: 3
a atRows: (1 to: 2) columns: (1 to: 2)
a atRows: (2 to: 3) columns: (2 to: 3)
"Assign sub-arrays"
a[(1 to: 2),(1 to: 2)] := Matrix[2, 2] fill: 1.
a[(2 to: 3),(2 to: 3)] := Matrix[2, 2] fill: 2.
Again, I had not bothered to implement this, not having had a need for it.
The new version will have
a atRows: 1 to: 2 columns: 1 to: 2 put:
(Matrix rows: 2 columns: 2 element: 1)
a atRows: 2 to: 3 columns: 2 to: 3 put:
(Matrix rows: 2 columns: 2 element: 2)
a atRows: (1 to: 2) columns: (1 to: 2) put:
(Matrix rows: 2 columns: 2 element: 1)
a atRows: (2 to: 3) columns: (2 to: 3) put:
(Matrix rows: 2 columns: 2 element: 2)
Again, I am in some doubt whether these should be ...put: or ...putAll: .
(Matrix>>rows:columns:element: is also new.)
a[#all,#all].
a[#all].
If these mean the same as
a copy
then that works, otherwise I don't understand the question.
"**** Dave''s examples ***"
"Matrix addition"
m1 := Matrix[3, 3] fill: #(1 2 3 4).
m2 := Matrix[3, 3] fill: #(10 20 30).
m3 := Matrix[3, 3] define: [:i1 :i2 | m1[i1, i2] + m2[i1, i2]].
I don't know what it means to fill a 3x3 matrix with a 4 element vector.
m1 := Matrix new: 3 tabulate: [:r :c | c]. " 1 2 3; 1 2 3; 1 2 3"
m2 := Matrix new: 3 tabulate: {:r :c | r*10]. "10 10 10; 20 20 20; 30 30 30"
m1 + m2
or if you really insist on the long-winded version:
m3 := Matrix new: tabulate [:r :c | (m1 at: r at: c) + (m2 at: r at: c)]
"Matrix Transpose"
Matrix shape: (m3 matrixShape reverse) define:[:i1 :i2 | m3[i2, i1]].
It doesn't get much simpler than
m3 transposed
"Matrix Multiplication (matrix product):"
m1 := Matrix[4, 3] fill: #(1 2 3 4 5 6 7).
m2 := Matrix[3, 2] fill: #(10 20 30 40).
m3 := Matrix[4, 2] define:[ :i1 : i2 | m1[i1,#all ] dot: m2[#all, i2]].
Again, I don't know what filling a matrix with a vector whose size is
different from all of {number of rows, number of columns, total number
of elements} is supposed to do, so I will concentrate on the last step.
m3 := m1 +* m2
"Laplace filter"
lap := Matrix[3,3] fill: #(1 4 1 4 -20 4 1 4 1).
lap := Matrix new: 3 tabulate: [:r :c |
(#((1 4 1) (4 -20 4) (1 4 1)) at: r) at: c]
image := Matrix[50,50] fill: 1.
image := Matrix new: 50 element: 1. "in new version."
fImage := Matrix[50,50] define:[:i1 :i2|
(image[(i1-1 to: i1+1), (i2-1 to: i2+1)] * lap) sum sum].
fImage := Matrix rows: 50 columns: 50 tabulate: [:r :c |
((image atRows: r-1 to: r+1 columns: c-1 to: c+1) +* lap) sum]
Beware: this does NOT work at the edges.
We need a new message which fills missing elements in.
The new version adds this:
fImage := Matrix rows: 50 columns: 50 tabulate: [:r :c |
((image atRows: r-1 to: r+1 columns: c-1 to: c+1 ifInvalid: 0)
+* lap) sum]
image := Matrix[53,53] fill: 1.
fImage := Matrix[50,50] define:[:i1 :i2|
(i1 at i2) printString displayAt: 0 at 0.
(image[(i1 to: i1+2), (i2 to: i2+2)] * lap) sum sum].
image := Matrix new: 53: fill: 1.
fImage := Matrix new: 50 tabulate: [:r :c |
(r at c) printString displayAt: 0 at 0.
((image atRows: r to: r+2 columns: c to: c+2) +* lap) sum]
For consistency with #(1 2 3) * #(4 5 6), it is important that the
symbol for matrix multiplication should NOT be *.
The examples above have been tested, but where retyped by hand, so may
contain typos.
More information about the Squeak-dev
mailing list
|