digitalmars.D.learn - 2D matrix operation (subtraction)
- Andre Pany (15/15) Feb 21 2020 Hi,
- =?UTF-8?Q?Ali_=c3=87ehreli?= (41/64) Feb 21 2020 0.8]];
- Andre Pany (11/74) Feb 21 2020 Thanks a lot. Mir is great and actually I try to rewrite some
- 9il (10/12) Feb 22 2020 Maybe mir.series [1] can work for you.
- Andre Pany (4/16) Feb 22 2020 Thanks a lot for all the answers.
- jmh530 (45/47) Feb 25 2020 I had a few other thoughts after looking at septc's solution of
- jmh530 (11/15) Feb 21 2020 mir has byDim for something similar (numir also has alongDim).
- jmh530 (5/6) Feb 21 2020 Actually, I kind of prefer the relevant line as
- septc (21/36) Feb 21 2020 I've recently learning Mir and so interested in
Hi, I have a 2D double array and I want to subtract from the first column a value, is this possible with matrix operation in D? ``` void main() { double[][] data = [[0.0, 1.4], [1.0, 5.2], [2.0, 0.8]]; // subtract -2.0 from the first column for every value // Expected output // data = [[-2.0, 1.4], [-1.0, 5.2], [0.0, 0.8]]; } ``` Kind regards André
Feb 21 2020
On 2/21/20 12:51 AM, Andre Pany wrote:Hi, =20 I have a 2D double array and I want to subtract from the first column a==20value, is this possible with matrix operation in D? =20 ``` void main() { =C2=A0=C2=A0=C2=A0 double[][] data =3D [[0.0, 1.4], [1.0, 5.2], [2.0, =0.8]];=20 =C2=A0=C2=A0=C2=A0 // subtract -2.0 from the first column for every va=lue=20 =C2=A0=C2=A0=C2=A0 // Expected output =C2=A0=C2=A0=C2=A0 // data =3D [[-2.0, 1.4], [-1.0, 5.2], [0.0, 0.8]];==20 } ``` =20 Kind regards Andr=C3=A9 =20 =20I don't have experience with it but mir's ndslice is designed for this: https://github.com/libmir/mir-algorithm Although it feels like something similar is probably already in Phobos,=20 I've come up with the following solution just now for fun: import std.stdio; import std.algorithm; import std.range; // At least something similar to this exists in Phobos? struct ElementReference(R) { ElementType!(ElementType!R) * p; ref reference() { return *p; } alias reference this; } struct Column(R) { R range; size_t n; auto empty() { return range.empty; } auto front() { return ElementReference!R(&(range.front[n])); } auto popFront() { return range.popFront(); } } auto byColumn(R)(R range, size_t n) { return Column!R(range, n); } void main() { double[][] data =3D [[0.0, 1.4], [1.0, 5.2], [2.0, 0.8]]; data.byColumn(0).each!(a =3D> a -=3D 2.0); writeln(data); } Ali
Feb 21 2020
On Friday, 21 February 2020 at 11:53:02 UTC, Ali Çehreli wrote:On 2/21/20 12:51 AM, Andre Pany wrote:Thanks a lot. Mir is great and actually I try to rewrite some Python Pandas Dataframe index logic. For my current project any dependency less is a little headache less, therefore I try to avoid Mir at the moment, but will definitely will have a look whether I can use it. Thanks for the example, I will use it. Kind regards AndréHi, I have a 2D double array and I want to subtract from the first column a value, is this possible with matrix operation in D? ``` void main() { double[][] data = [[0.0, 1.4], [1.0, 5.2], [2.0, 0.8]]; // subtract -2.0 from the first column for every value // Expected output // data = [[-2.0, 1.4], [-1.0, 5.2], [0.0, 0.8]]; } ``` Kind regards AndréI don't have experience with it but mir's ndslice is designed for this: https://github.com/libmir/mir-algorithm Although it feels like something similar is probably already in Phobos, I've come up with the following solution just now for fun: import std.stdio; import std.algorithm; import std.range; // At least something similar to this exists in Phobos? struct ElementReference(R) { ElementType!(ElementType!R) * p; ref reference() { return *p; } alias reference this; } struct Column(R) { R range; size_t n; auto empty() { return range.empty; } auto front() { return ElementReference!R(&(range.front[n])); } auto popFront() { return range.popFront(); } } auto byColumn(R)(R range, size_t n) { return Column!R(range, n); } void main() { double[][] data = [[0.0, 1.4], [1.0, 5.2], [2.0, 0.8]]; data.byColumn(0).each!(a => a -= 2.0); writeln(data); } Ali
Feb 21 2020
On Friday, 21 February 2020 at 13:42:24 UTC, Andre Pany wrote:Mir is great and actually I try to rewrite some Python Pandas Dataframe index logic.Maybe mir.series [1] can work for you. Series!(Key*, Value*) - is a pair of two 1D ndslices, they can be sorted according to the first one ndslice (keys). Series has `get` methods. Series!(Key*, Value*, 2) is a pair of 1D ndslice (keys) and 2D ndslice (values matrix). Series has slicing primitives. Keys corresponds to the first dimension. http://mir-algorithm.libmir.org/mir_series.html#Series
Feb 22 2020
On Saturday, 22 February 2020 at 08:29:32 UTC, 9il wrote:On Friday, 21 February 2020 at 13:42:24 UTC, Andre Pany wrote:Thanks a lot for all the answers. Kind regards AndreMir is great and actually I try to rewrite some Python Pandas Dataframe index logic.Maybe mir.series [1] can work for you. Series!(Key*, Value*) - is a pair of two 1D ndslices, they can be sorted according to the first one ndslice (keys). Series has `get` methods. Series!(Key*, Value*, 2) is a pair of 1D ndslice (keys) and 2D ndslice (values matrix). Series has slicing primitives. Keys corresponds to the first dimension. http://mir-algorithm.libmir.org/mir_series.html#Series
Feb 22 2020
On Saturday, 22 February 2020 at 08:29:32 UTC, 9il wrote:[snip] Maybe mir.series [1] can work for you.I had a few other thoughts after looking at septc's solution of using y[0..$, 0] *= 100; to do the calculation. 1) There is probably scope for an additional select function to handle the use case of choosing a specific row/column. For instance, what if instead of y[0..$, 0] you want y[0..$, b, 0..$] for some arbitrary b. I think you would need to do something like y.select!1(b, b + 1); which doesn't have the best API, IMO, because you have to repeat b. Maybe just an overload for select that only takes one input instead of two? 2) The select series of functions does not seem to work as easily as array indexing does. When I tried to use the select/selectFront functions to do what he is doing, I had to something like auto z = y.selectFront!1(1); z[] *= 100; This would adjust y as expected (not z). However, I couldn't figure out how to combine these together to one line. For instance, I couldn't do y.selectFront!1(1) *= 100; or auto y = x.selectFront!1(1).each!(a => a * 100); though something like y[0..$, 0].each!"a *= 100"; works without issue. It got a little frustrating to combine those with any kind of iteration. TBH, I think more than the select functions, the functionality I would probably be looking for is more what I was doing with byDim!1[0] in the prior post. I could imagine some very simple version looking like below auto selectDim(size_t dim, T)(T x, size_t a, size_t b) { return byDim!dim[a .. b]; } with a corresponding version auto selectDim(size_t dim, T)(T x, size_t a) { return byDim!dim[a .. (a + 1)]; } This simple version would only work with one dimension, even though byDim can handle multiple.
Feb 25 2020
On Friday, 21 February 2020 at 11:53:02 UTC, Ali Çehreli wrote:[snip] auto byColumn(R)(R range, size_t n) { return Column!R(range, n); }mir has byDim for something similar (numir also has alongDim). This is how you would do it: import mir.ndslice; void main() { auto x = [0.0, 1.4, 1.0, 5.2, 2.0, 0.8].sliced(3, 2); x.byDim!1.front.each!"a -= 2"; } My recollection is that it is a little bit trickier if you want to subtract a vector from each column of a matrix (the sweep function in R).
Feb 21 2020
On Friday, 21 February 2020 at 14:43:37 UTC, jmh530 wrote:[snip]Actually, I kind of prefer the relevant line as x.byDim!1[0].each!"a -= 2"; which makes it a little clearer that you can easily change [0] to [1] to apply each to the second column instead.
Feb 21 2020
On Friday, 21 February 2020 at 08:51:49 UTC, Andre Pany wrote:Hi, I have a 2D double array and I want to subtract from the first column a value, is this possible with matrix operation in D? ``` void main() { double[][] data = [[0.0, 1.4], [1.0, 5.2], [2.0, 0.8]]; // subtract -2.0 from the first column for every value // Expected output // data = [[-2.0, 1.4], [-1.0, 5.2], [0.0, 0.8]]; } ``` Kind regards AndréI've recently learning Mir and so interested in this topic. For the above purpose, I am wondering if this Numpy-like approach is also valid: y[ 0..$, 0 ] *= 100; The online editor (https://run.dlang.io/) seems to give the expected result. // (the below code is based on the post by jmh530) import std.stdio; import mir.ndslice; void main() { auto x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0].sliced(3, 2); auto y = x.dup; writeln( x ); // [[0, 1], [2, 3], [4, 5]] writeln( y ); // [[0, 1], [2, 3], [4, 5]] x.byDim!1.front.each!"a *= 100"; y[ 0..$, 0 ] *= 100; writeln( x ); // [[0, 1], [200, 3], [400, 5]] writeln( y ); // [[0, 1], [200, 3], [400, 5]] }
Feb 21 2020