digitalmars.D.learn - transversal sum
- Jack Applegame (18/18) Nov 06 2014 I have rectangular forward range of forward ranges (not arrays):
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (5/23) Nov 06 2014 Untested:
- Justin Whear (8/35) Nov 06 2014 This would sum along the wrong dimension. I think the correct solution
- Justin Whear (2/6) Nov 06 2014 That should be std.range.frontTransversal and transversal.
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (6/16) Nov 06 2014 Yeah, I posted to soon. Was surprised that the solution would be
- bearophile (5/8) Nov 06 2014 A simple solution is to create a row of values, and then sum them
- Artur Skawina via Digitalmars-d-learn (17/22) Nov 06 2014 The simplest solution is probably something like:
- Jack Applegame (3/6) Nov 06 2014 exactly.
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (4/31) Nov 06 2014 Sorry, I see you want columns...
- John Colvin (3/21) Nov 06 2014 Can I get random access in one or both dimensions?
- John Colvin (3/28) Nov 06 2014 with random access along N:
- John Colvin (18/36) Nov 06 2014 nasty inefficient solution, but might be ok if your ranges have
- John Colvin (4/22) Nov 06 2014 this should be a textbook case for std.range.transposed, but I
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (21/23) Nov 07 2014 Ah, I didn't know this existed. Apparently it's not yet released,
- bearophile (8/21) Nov 07 2014 You "input" range is not just a Forward Range.
- bearophile (9/12) Nov 07 2014 And that part is better written:
- John Colvin (3/26) Nov 07 2014 http://dlang.org/phobos-prerelease/std_range.html#.transposed
I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?
Nov 06 2014
On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?Untested: import std.algorithm: map, sum; auto rangeOfSums = rectangularRange.map!(r => r.sum);
Nov 06 2014
On Thu, 06 Nov 2014 16:57:48 +0000, Marc Schütz wrote:On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:This would sum along the wrong dimension. I think the correct solution will make use of std.range.frontTraversal, but it will be a bit more complex due to needing to sum every column. std.range.traversal would make it easy, but it requires random access.I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?Untested: import std.algorithm: map, sum; auto rangeOfSums = rectangularRange.map!(r => r.sum);
Nov 06 2014
On Thu, 06 Nov 2014 17:08:23 +0000, Justin Whear wrote:I think the correct solution will make use of std.range.frontTraversal, but it will be a bit more complex due to needing to sum every column. std.range.traversal would make it easy, but it requires random access.That should be std.range.frontTransversal and transversal.
Nov 06 2014
On Thursday, 6 November 2014 at 17:08:23 UTC, Justin Whear wrote:This would sum along the wrong dimension. I think the correct solution will make use of std.range.frontTraversal, but it will be a bit more complex due to needing to sum every column. std.range.traversal would make it easy, but it requires random access.Yeah, I posted to soon. Was surprised that the solution would be so easy :-P We'd need something taking and returning a RoR that "mirrors" them diagonally. Then we could simply apply `map!(r => r.sum)` on the result.
Nov 06 2014
Marc Schütz:We'd need something taking and returning a RoR that "mirrors" them diagonally. Then we could simply apply `map!(r => r.sum)` on the result.A simple solution is to create a row of values, and then sum them correctly while you scan the rows. Bye, bearophile
Nov 06 2014
On 11/06/14 18:32, bearophile via Digitalmars-d-learn wrote:Marc Schütz:The simplest solution is probably something like: auto transversal_sum(FR)(FR rr) { static struct TS { FR rr; bool empty() property const { return rr.front.empty; } auto front() property { import std.algorithm; return reduce!((a, b)=>a+b.front)(rr.front.front.init, rr); } void popFront() { foreach (ref r; rr) r.popFront(); } } return TS(rr); } but I think OP wanted a ready-made phobos solution, w/o all the range boilerplate... arturWe'd need something taking and returning a RoR that "mirrors" them diagonally. Then we could simply apply `map!(r => r.sum)` on the result.A simple solution is to create a row of values, and then sum them correctly while you scan the rows.
Nov 06 2014
void popFront() { foreach (ref r; rr) r.popFront(); }I think it should be void popFront() { foreach (ref r; rr.save) r.popFront(); }but I think OP wanted a ready-made phobos solution, w/o all the range boilerplate...exactly.
Nov 06 2014
On Thursday, 6 November 2014 at 16:57:50 UTC, Marc Schütz wrote:On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:Sorry, I see you want columns... I thought about std.range.frontTransversal, but it only returns a range of values, not a range of ranges. That's... unhelpful :-(I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?Untested: import std.algorithm: map, sum; auto rangeOfSums = rectangularRange.map!(r => r.sum);
Nov 06 2014
On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?Can I get random access in one or both dimensions?
Nov 06 2014
On Thursday, 6 November 2014 at 22:02:09 UTC, John Colvin wrote:On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:with random access along N: iota(N).map!((i) => ror.transversal(i).sum())I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?Can I get random access in one or both dimensions?
Nov 06 2014
On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?nasty inefficient solution, but might be ok if your ranges have cheap popFront: import std.algorithm, std.range, std.stdio, std.array; void main() { auto M = 3; auto N = 10; //generate a RangeOfRanges for testing auto ror = iota(1, M+1) .map!(l => iota(N) .map!(e => e * l^^2)); auto rorFlat = ror.joiner; iota(N) .map!(i => rorFlat.save.drop(i).stride(N)) .map!sum.writeln; }
Nov 06 2014
On Thursday, 6 November 2014 at 15:53:27 UTC, Jack Applegame wrote:I have rectangular forward range of forward ranges (not arrays): [ [a11, a12, ... a1N], [a21, a22, ... a2N], ... [aM1, aM2, ... aMN] ] I need lazy forward range: [ a11 + a21 + ... aM1, a12 + a22 + ... aM2, ... a1N + a2N + ... aMN ] Range of sum elements of every columns; M, N - runtime values; Is there a way to do this using only Phobos algorithms and range functions?this should be a textbook case for std.range.transposed, but I can't seem to get it to work.
Nov 06 2014
On Thursday, 6 November 2014 at 22:40:58 UTC, John Colvin wrote:this should be a textbook case for std.range.transposed, but I can't seem to get it to work.Ah, I didn't know this existed. Apparently it's not yet released, that's why it's not in the official documentation. With DMD and Phobos from git: void main(string[] args) { import std.stdio: writeln; import std.range: transposed; import std.algorithm: map, sum; int[][] input = new int[][2]; input[0] = [1, 2, 3, 4]; input[1] = [5, 6, 7, 8]; writeln(input); auto sums = input .transposed .map!(a => a.sum); writeln(sums); } Output: [[1, 2, 3, 4], [5, 6, 7, 8]] [6, 8, 10, 12]
Nov 07 2014
Marc Schütz:int[][] input = new int[][2]; input[0] = [1, 2, 3, 4]; input[1] = [5, 6, 7, 8]; writeln(input); auto sums = input .transposed .map!(a => a.sum); writeln(sums); } Output: [[1, 2, 3, 4], [5, 6, 7, 8]] [6, 8, 10, 12]Jack specified:I have rectangular forward range of forward ranges (not arrays):You "input" range is not just a Forward Range. And by the way, your array literal can be written more simply like this: int[][2] input = [[1, 2, 3, 4], [5, 6, 7, 8]]; Bye, bearophile
Nov 07 2014
Marc Schütz:auto sums = input .transposed .map!(a => a.sum);And that part is better written: .map!sum; I also suggest to align the leading dot to the precedent line: auto sums = input .transposed .map!(a => a.sum); Bye, bearophile
Nov 07 2014
On Friday, 7 November 2014 at 10:58:58 UTC, Marc Schütz wrote:On Thursday, 6 November 2014 at 22:40:58 UTC, John Colvin wrote:yeah it works find for arrays, but it needs assignable elements.this should be a textbook case for std.range.transposed, but I can't seem to get it to work.Ah, I didn't know this existed. Apparently it's not yet released, that's why it's not in the official documentation. With DMD and Phobos from git: void main(string[] args) { import std.stdio: writeln; import std.range: transposed; import std.algorithm: map, sum; int[][] input = new int[][2]; input[0] = [1, 2, 3, 4]; input[1] = [5, 6, 7, 8]; writeln(input); auto sums = input .transposed .map!(a => a.sum); writeln(sums); } Output: [[1, 2, 3, 4], [5, 6, 7, 8]] [6, 8, 10, 12]
Nov 07 2014