MatrixAccessor.st
author Stefan Vogel <sv@exept.de>
Thu, 12 Dec 2019 19:01:46 +0100
changeset 25102 5e2a71db9286
parent 24678 c52690dca84a
child 25121 d3591d0375df
permissions -rw-r--r--
#FEATURE by stefan class: UnixOperatingSystem class changed: #voiceCommandSpec support read from stdIn

"{ Encoding: utf8 }"

"{ 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 sequenceable collections.
    Allows arbitrary collections which offer access by an integer index
    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.
!

dimensions
    ^ dimensions 

!

size
    ^ dimensions inject:1 into:[:szSoFar :thisDim | szSoFar * thisDim].
! !

!MatrixAccessor methodsFor:'private-initialization'!

collection:arrayArg dimensions:dimensionsArg
    array := arrayArg.
    dimensions := dimensionsArg.
! !

!MatrixAccessor methodsFor:'queries'!

isSquare
    ^ dimensions size == 2
    and:[(dimensions at:1) == (dimensions at:2)]
! !

!MatrixAccessor class methodsFor:'documentation'!

version_CVS
    ^ '$Header$'
! !