initial checkin
authorClaus Gittinger <cg@exept.de>
Wed, 21 Aug 2019 22:51:29 +0200
changeset 24575 23c9b73d0a4f
parent 24574 da29ade15da2
child 24576 168b47ad4e71
initial checkin
MatrixAccessor.st
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MatrixAccessor.st	Wed Aug 21 22:51:29 2019 +0200
@@ -0,0 +1,204 @@
+"{ Package: 'stx:libbasic' }"
+
+"{ NameSpace: Smalltalk }"
+
+AbstractMultidimensionalArray variableSubclass:#MatrixAccessor
+	instanceVariableNames:'array dimensions'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Collections-MultiDimensional'
+!
+
+!MatrixAccessor class methodsFor:'documentation'!
+
+documentation
+"
+    Matrix-Access for arbitrary sequentiable collections.
+    Allows arbitrary collections to function as matrices.
+
+    [author:]
+        Claus Gittinger (cg@sinir)
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+        Matrix
+"
+!
+
+examples
+"
+  You have to enable the Parsers arrayIndexingExtension support
+  in order to be able to execute the examples below.
+
+  Parser allowArrayIndexSyntaxExtension:true
+                                                                [exBegin]
+    |m|
+
+    m := FloatArray[3,3].
+    m [2,1] := 1.  
+    m [2,2] := 2.  
+    m [2,3] := 3.  
+    m     
+                                                                [exEnd]
+"
+! !
+
+!MatrixAccessor class methodsFor:'instance creation'!
+
+collection:coll dimensions:dimensions
+    ^ self new collection:coll dimensions:dimensions
+! !
+
+!MatrixAccessor methodsFor:'accessing'!
+
+_at:index
+    "this is a synthetic selector, generated by the compiler,
+     if a construct of the form expr[idx...] is parsed.
+     I.e. 
+        foo[n]
+     generates
+        foo _at: n
+    "
+    dimensions size ~~ 1 ifTrue:[self dimensionError].
+    ^ array at:index.
+!
+
+_at:index1 at:index2
+    "this is a synthetic selector, generated by the compiler,
+     if a construct of the form expr[idx...] is parsed.
+     I.e. 
+        foo[n,m]
+     generates
+        foo _at:n at:m
+    "
+    |idx|
+
+    dimensions size ~~ 2 ifTrue:[self dimensionError].
+    (index1 between:1 and:(dimensions at:1)) ifFalse:[self subscriptBoundsError:index1].
+    (index2 between:1 and:(dimensions at:2)) ifFalse:[self subscriptBoundsError:index2].
+
+    idx := ((index1-1) * (dimensions at:2)).
+    idx := idx + index2.
+    ^ array at:idx.
+!
+
+_at:index1 at:index2 at:index3
+    "this is a synthetic selector, generated by the compiler,
+     if a construct of the form expr[idx...] is parsed.
+     I.e. 
+        foo[n,m,o]
+     generates
+        foo _at:n at:m at:o
+    "
+    |idx|
+
+    dimensions size ~~ 3 ifTrue:[self dimensionError].
+    (index1 between:1 and:(dimensions at:1)) ifFalse:[self subscriptBoundsError:index1].
+    (index2 between:1 and:(dimensions at:2)) ifFalse:[self subscriptBoundsError:index2].
+    (index3 between:1 and:(dimensions at:3)) ifFalse:[self subscriptBoundsError:index3].
+
+    idx := ((((index1-1) * (dimensions at:2)) + (index2-1)) * (dimensions at:3)).
+    idx := idx + index3.
+    ^ array at:idx.
+
+    "
+     |m|
+     m := MatrixAccessor new
+              collection:
+                #(
+                   111 112 113 114
+                   121 122 123 124
+                   131 132 133 134
+
+                   211 212 213 214
+                   221 222 223 224
+                   231 232 233 234 )
+              dimensions:
+                #(2 3 4).
+
+     m[2,1,4]          
+    "
+!
+
+_at:index1 at:index2 at:index3 put:val
+    "this is a synthetic selector, generated by the compiler,
+     if a construct of the form expr[idx...] := val is parsed.
+     I.e. 
+        foo[n,m,o] := val
+     generates
+        foo _at:n at:m at:o put:val
+    "
+    |idx|
+
+    dimensions size ~~ 3 ifTrue:[self dimensionError].
+    (index1 between:1 and:(dimensions at:1)) ifFalse:[self subscriptBoundsError:index1].
+    (index2 between:1 and:(dimensions at:2)) ifFalse:[self subscriptBoundsError:index2].
+    (index3 between:1 and:(dimensions at:3)) ifFalse:[self subscriptBoundsError:index3].
+
+    idx := ((((index1-1) * (dimensions at:2)) + (index2-1)) * (dimensions at:3)).
+    idx := idx + index3.
+    ^ array at:idx put:val.
+!
+
+_at:index1 at:index2 put:val
+    "this is a synthetic selector, generated by the compiler,
+     if a construct of the form expr[idx...] := val is parsed.
+     I.e. 
+        foo[n,m] := val
+     generates
+        foo _at:n at:m put:val
+    "
+    |idx|
+
+    dimensions size ~~ 2 ifTrue:[self dimensionError].
+    (index1 between:1 and:(dimensions at:1)) ifFalse:[self subscriptBoundsError:index1].
+    (index2 between:1 and:(dimensions at:2)) ifFalse:[self subscriptBoundsError:index2].
+
+    idx := ((index1-1) * (dimensions at:2)).
+    idx := idx + index2.
+    ^ array at:idx put:val.
+!
+
+_at:index put:val
+    "this is a synthetic selector, generated by the compiler,
+     if a construct of the form expr[idx...] := val is parsed.
+     I.e. 
+        foo[n] := val
+     generates
+        foo _at:n put:val
+    "
+    dimensions size ~~ 1 ifTrue:[self dimensionError].
+
+    ^ array at:index put:val.
+!
+
+at:index
+    "/ dimensions size ~~ 1 ifTrue:[self dimensionError].
+    ^ array at:index.
+!
+
+at:index put:val
+    "/ dimensions size ~~ 1 ifTrue:[self dimensionError].
+    ^ array at:index put:val.
+!
+
+size
+    ^ dimensions inject:1 into:[:szSoFar :thisDim | szSoFar * thisDim].
+! !
+
+!MatrixAccessor methodsFor:'private-initialization'!
+
+collection:arrayArg dimensions:dimensionsArg
+    array := arrayArg.
+    dimensions := dimensionsArg.
+! !
+
+!MatrixAccessor class methodsFor:'documentation'!
+
+version_CVS
+    ^ '$Header$'
+! !
+