www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 10304] New: Array operations for multi-dimensional fixed-sized arrays with the same size

http://d.puremagic.com/issues/show_bug.cgi?id=10304

           Summary: Array operations for multi-dimensional fixed-sized
                    arrays with the same size
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



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; -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jun 08 2013