The Inbox: Collections-cbc.769.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Collections-cbc.769.mcz

commits-2
A new version of Collections was added to project The Inbox:
http://source.squeak.org/inbox/Collections-cbc.769.mcz

==================== Summary ====================

Name: Collections-cbc.769
Author: cbc
Time: 27 November 2017, 1:21:09.685285 pm
UUID: 59c54629-954c-504d-87a9-cb745d5e9188
Ancestors: Collections-nice.768

Updated Matrix comment to be consistent by itself (instead of only in comparison to Array2D, which isn't in the system).
Added ...ifAbsent: pairs to the ...ifInvalid: calls, to be more standard, but left the ...ifInvalid: in place (useful if you want to present the matrix is not fixed size).
Added some nicer named methods like #atRow:column: to be more specific about what is called, but left old #at:at: to not inconvenience previous users.

=============== Diff against Collections-nice.768 ===============

Item was changed:
  Collection subclass: #Matrix
  instanceVariableNames: 'nrows ncols contents'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'Collections-Unordered'!
 
+ !Matrix commentStamp: 'cbc 11/27/2017 13:10' prior: 0!
+ I represent a two-dimensional array.
- !Matrix commentStamp: '<historical>' prior: 0!
- I represent a two-dimensional array, rather like Array2D.
- There are three main differences between me and Array2D:
- (1) Array2D inherits from ArrayedCollection, but isn't one.  A lot of things that should work
-     do not work in consequence of this.
- (2) Array2D uses "at: column at: row" index order, which means that nothing you write using
-     it is likely to work either.  I use the almost universal "at: row at: column" order, so it is
-     much easier to adapt code from other languages without going doolally.
- (3) Array2D lets you specify the class of the underlying collection, I don't.
 
+ I use an underlying Array to hold the elements, but present a row by column access to the array.  In particular, I use the almost universal "at: row at: column" order, so it is much easier to adapt code from other languages without going doolally.
+
  Structure:
    nrows : a non-negative integer saying how many rows there are.
    ncols : a non-negative integer saying how many columns there are.
    contents : an Array holding the elements in row-major order.  That is, for a 2x3 array
+     the contents are (11 12 13 21 22 23).
+     (show in graphical form:
+      11  21
+      12  22
+      13  23
+     )
-     the contents are (11 12 13 21 22 23).  Array2D uses column major order.
 
+     Another reason (besides speed) for always insisting on an Array is that letting it be something
-     You can specify the class of 'contents' when you create a new Array2D,
-     but Matrix always gives you an Array.
-
-     There is a reason for this.  In strongly typed languages like Haskell and Clean,
-     'unboxed arrays' save you both space AND time.  But in Squeak, while
-     WordArray and FloatArray and so on do save space, it costs time to use them.
-     A LOT of time.  I've measured aFloatArray sum running nearly twice as slow as
-     anArray sum.  The reason is that whenever you fetch an element from an Array,
-     that's all that happens, but when you fetch an element from aFloatArray, a whole
-     new Float gets allocated to hold the value.  This takes time and churns memory.
-     So the paradox is that if you want fast numerical stuff, DON'T use unboxed arrays!!
-
-     Another reason for always insisting on an Array is that letting it be something
      else would make things like #, and #,, rather more complicated.  Always using Array
      is the simplest thing that could possibly work, and it works rather well.
 
- I was trying to patch Array2D to make more things work, but just couldn't get my head
- around the subscript order.  That's why I made Matrix.
-
  Element-wise matrix arithmetic works; you can freely mix matrices and numbers but
  don't try to mix matrices and arrays (yet).
  Matrix multiplication, using the symbol +* (derived from APL's +.x), works between
  (Matrix or Array) +* (Matrix or Array).  Don't try to use a number as an argument of +*.
  Matrix * Number and Number * Matrix work fine, so you don't need +* with numbers.
 
  Still to come: oodles of stuff.  Gaussian elimination maybe, other stuff probably not.
+
+ original author: roak!
- !

Item was changed:
  ----- Method: Matrix>>at:at: (in category 'accessing') -----
  at: row at: column
+ ^self atRow: row column: column!
- ^contents at: (self indexForRow: row andColumn: column)!

Item was added:
+ ----- Method: Matrix>>at:at:ifAbsent: (in category 'accessing') -----
+ at: r at: c ifAbsent: absentBlock
+ ^self atRow: r column: c ifAbsent: absentBlock!

Item was changed:
  ----- Method: Matrix>>at:at:ifInvalid: (in category 'accessing') -----
  at: r at: c ifInvalid: v
  "If r,c is a valid index for this matrix, answer the corresponding element.
  Otherwise, answer v."
+ ^self atRow: r column: c ifAbsent: [v]
+ "Note: the ..ifInvalid: option is useful is pretending the matrix isn't a fixed size."!
-
- (r between: 1 and: nrows) ifFalse: [^v].
- (c between: 1 and: ncols) ifFalse: [^v].
- ^contents at: (r-1)*ncols + c
- !

Item was changed:
  ----- Method: Matrix>>at:at:put: (in category 'accessing') -----
  at: row at: column put: value
+ ^self atRow: row column: column put: value!
- ^contents at: (self indexForRow: row andColumn: column) put: value!

Item was added:
+ ----- Method: Matrix>>atRow:column: (in category 'accessing') -----
+ atRow: row column: column
+ ^contents at: (self indexForRow: row andColumn: column)!

Item was added:
+ ----- Method: Matrix>>atRow:column:ifAbsent: (in category 'accessing') -----
+ atRow: r column: c ifAbsent: absentBlock
+ "If r,c is a valid index for this matrix, answer the corresponding element.
+ Otherwise, answer absentBlock value."
+
+ (r between: 1 and: nrows) ifFalse: [^absentBlock value].
+ (c between: 1 and: ncols) ifFalse: [^absentBlock value].
+ ^contents at: (r-1)*ncols + c
+ !

Item was added:
+ ----- Method: Matrix>>atRow:column:put: (in category 'accessing') -----
+ atRow: row column: column put: value
+ ^contents at: (self indexForRow: row andColumn: column) put: value!