Bug 10304 – Array operations for multi-dimensional fixed-sized arrays with the same size

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-06-08T14:46:49Z
Last change time
2024-12-13T18:07:58Z
Assigned to
No Owner
Creator
bearophile_hugs
Moved to GitHub: dmd#18605 →

Comments

Comment #0 by bearophile_hugs — 2013-06-08T14:46:49Z
void main() { double[3][2] mat = 1.0; foreach (ref row; mat) row[] *= 3; // OK mat[] *= 3; // line 5, error. } dmd 2.064alpha gives: temp.d(5): Error: incompatible types for ((mat[]) *= (3)): 'double[3u][]' and 'int' Line 5 is an error because currently the D built-in array operations only work with 1D arrays. But the need to operate on all items of a 2D array is very commonly needed operation in the kind of array-heavy scientific code often written in Matlab or Python+SciPy. This is in Python command line: >>> from numpy import * >>> mat = zeros((2, 3)) >>> mat array([[ 0., 0., 0.], [ 0., 0., 0.]]) >>> mat[:] = 1 >>> mat array([[ 1., 1., 1.], [ 1., 1., 1.]]) >>> mat *= 3 >>> mat array([[ 3., 3., 3.], [ 3., 3., 3.]]) So I suggest to support array ops with 2D or nD arrays (especially if they are fixed-sized arrays, so they are just a single chunk of memory, so the array op becomes just a matter of seeing the array in a linearized way). One D syntax to support such operation is the same as for 1D arrays, I think this syntax is acceptable: double[3][2] mat = 1.0; mat[] *= 3; If you really want to tell apart the 1D case from the nD case, then this is an alternative syntax, but I think it's not needed: mat[][] *= 3; To implement the matrix-wide operations this is a work-around that can be used now: mat.flatView *= 3; where flatView is similar to: auto flatView(size_t R, size_t C)(ref double[C][R] mat) pure nothrow { static struct FlatView(size_t N) { double* ptr; void opOpAssign(string op)(in double k) pure nothrow if (op == "*") { ptr[0 .. N] *= k; } } return FlatView!(R * C)(mat[0].ptr); } Currently built-in array ops are designed to not t allocate intermediate arrays, so in the following code the multiplication doesn't allocate an intermediate array: double[3] position2, velocity2; double delta2 = 3.5; position2[] += delta2 * velocity2[]; This too can be implemented by the compiler without intermediate arrays: double[3][2] position, velocity; double delta = 3.5; position[] += delta * velocity[]; But its' not immediate to create a flatView() usable like this that doesn't allocate intermediate arrays: double[3][2] position, velocity; double delta = 3.5; position.flatView += delta * velocity.flatView;
Comment #1 by robert.schadek — 2024-12-13T18:07:58Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18605 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB