MatrixAccessor.st
author Stefan Vogel <sv@exept.de>
Wed, 11 Mar 2020 10:09:01 +0100
changeset 25334 8f44c9352333
parent 25121 d3591d0375df
permissions -rw-r--r--
#BUGFIX by stefan class: Smalltalk class changed: #hello Fix welcome messages for kanguages != #en

"{ Encoding: utf8 }"

"
 COPYRIGHT (c) 2018 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libbasic' }"

"{ NameSpace: Smalltalk }"

AbstractMultidimensionalArray variableSubclass:#MatrixAccessor
	instanceVariableNames:'array dimensions'
	classVariableNames:''
	poolDictionaries:''
	category:'Collections-MultiDimensional'
!

!MatrixAccessor class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2018 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

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$'
! !