[Issue 10304] New: Array operations for multi-dimensional fixed-sized arrays with the same size
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Jun 8 14:46:51 PDT 2013
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 at puremagic.com
ReportedBy: bearophile_hugs at eml.cc
--- Comment #0 from bearophile_hugs at eml.cc 2013-06-08 14:46:49 PDT ---
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: -------
More information about the Digitalmars-d-bugs
mailing list