class Matrix 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 Test def main 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