""" Run with -turbo for max speed (no run-time checks). """ class Matrix """ This class provides an n-dimensional matrix containing any other type. The class provides initialization for any number of dimensions, access to the data via indexing (`m[a, b, c]`) and equality comparisons between matrices. The dimension sizes and even the number of dimensions may be hard-coded or delayed until run-time. There are, of course, many other conveniences that a developer may want from this class, but they vary from developer to developer or even project to project. This class focuses on providing the basics with correct implementation of n-dimensions. Feel free to subclass this or even copy it into your project for customization. """ const minDimRank = 1 const maxDimRank = 1_000_000 const maxCount = 1_000_000_000 var _dims as IList var _count = 1 var _data as T[] cue init(dims as vari int) require dims.length > 0 and all for dim in dims get dim >= .minDimRank and dim <= .maxDimRank .init(dims.toList) cue init(dims as IList) require dims.count > 0 and all for dim in dims get dim >= .minDimRank and dim <= .maxDimRank base.init _dims = dims.clone for dim in dims, _count *= dim assert _count < .maxCount _data = T[](_count) assert _data.length == _count get count from var get dims as IList return _dims.clone pro [indexes as vari int] as T get require indexes.length == .dims.count return _data[_address(indexes)] set require indexes.length == .dims.count _data[_address(indexes)] = value def _address(indexes as vari int) as int assert indexes.length == _dims.count # The below calcs are "row-major order", if it matters. # See http://en.wikipedia.org/wiki/Row-major_order#Generalization_to_higher_dimensions address = 0 len = indexes.length for i in len index = indexes[i] if index < 0 or index >= _dims[i] throw IndexOutOfRangeException('Array index [index] is out of range 0 - [_dims[i]] for dimension [i].') x = 1 for j in i+1 : len, x *= _dims[j] x *= index address += x return address def equals(obj as Object?) as bool is override if obj inherits Matrix, return .equals(obj) return false def getHashCode as int is override throw InvalidOperationException() def equals(m as Matrix) as bool if m.count <> .count, return false if m._dims <> _dims, return false for i in _count, if m._data[i] <> _data[i], return false return true class TestMatrix test m = Matrix(1) assert m.count == 1 assert m[0] == 0 m[0] = 42 assert m[0] == 42 expect IndexOutOfRangeException, print m[1] m = Matrix(3, 7) assert m.count == 21 for x in 3, for y in 7, m[x, y] = x*y for x in 3, for y in 7, assert m[x, y] == x*y expect IndexOutOfRangeException, print m[3, 7] expect IndexOutOfRangeException, print m[3, 0] expect IndexOutOfRangeException, print m[0, 7] expect IndexOutOfRangeException, print m[4, 8] d1, d2, d3 = 10, 5, 3 m = Matrix(d1, d2, d3) assert m.count == d1 * d2 * d3 for x in d1, for y in d2, for z in d3, m[x, y, z] = x*y*z for x in d1, for y in d2, for z in d3, assert m[x, y, z] == x*y*z dims = [d1, d2, d3] m2 = Matrix(dims) for x in d1, for y in d2, for z in d3, m2[x, y, z] = x*y*z for x in d1, for y in d2, for z in d3, assert m2[x, y, z] == x*y*z assert m2 == m m2[0, 0, 0] += 1 assert m2 <> m def main print 'done.'