Thread overview
specifying an auto array type
Dec 27, 2015
Jay Norwood
Dec 27, 2015
Ali Çehreli
Dec 27, 2015
Jay Norwood
Dec 27, 2015
Ali Çehreli
December 27, 2015
This is getting kind of a long example, but I'm really only interested in the last 4 or 5 lines. This works as desired, creating the array of tuples, but I'm wondering if there is a way to have the Tuple array defined as auto instead of having to specify the types.  I tried using .array() at the end of the last samples.each!, but couldn't find an implementation that worked.

Yes, I know, some of these imports aren't required (yet).

import std.stdio;
import std.algorithm;
import std.conv;
import std.range;
import std.typecons;
import std.parallelism;
import std.array;

struct S { ulong a; ulong b; ulong c; ulong d; double e; ulong f;}
ulong f1(ref S s) { with(s){return a+b;}}
double f2(ref S s) { with(s){return (c+d)/e;}}
double f3(ref S s) { with(s){return (c+f)/e;}}

int main()
{

	S[10] samples;
	// initialize some values
	foreach ( int i, ref s; samples){
		int j=i+1;
		with (s){
			a=j; b=j*2; c=j*3; d=j*4; e=j*10; f=j*5;
		}
	}

	// apply several functions on each  sample
	samples.each!((int i, ref a)=>tuple!("sample","f1","f2","f3")(i,f1(a),f2(a),f3(a)).writeln());

	// output the function results to an array of tuples
	Tuple!(int, ulong, double, double)[] arr;

	samples.each!((int i, ref a)=> arr ~= tuple!("sample","f1","f2","f3")(i,f1(a),f2(a),f3(a)));
	writeln(arr);
	return 0;
}
December 26, 2015
On 12/26/2015 09:45 PM, Jay Norwood wrote:

> This is getting kind of a long example,

There are issues with that code that make it hard for me to guess the intent.

> a way to have the Tuple array defined as auto instead of having to specify
> the types.  I tried using .array() at the end of the last samples.each!, but
> couldn't find an implementation that worked.

It looks like you need map(), not each():

import std.algorithm;
import std.typecons;
import std.array;

void main() {
    auto a = [ 1, 2 ];
    auto arr = a.map!(e => tuple(2 * e, e * e)).array;

    static assert(is(typeof(arr) == Tuple!(int, int)[]));
}

Ali

December 27, 2015
On Sunday, 27 December 2015 at 07:40:55 UTC, Ali Çehreli wrote:
>
> It looks like you need map(), not each():
>
> import std.algorithm;
> import std.typecons;
> import std.array;
>
> void main() {
>     auto a = [ 1, 2 ];
>     auto arr = a.map!(e => tuple(2 * e, e * e)).array;
>
>     static assert(is(typeof(arr) == Tuple!(int, int)[]));
> }
>
> Ali

ok, thanks.  This does work, using the uint i ahead of the map statement.

uint i=0;
auto arr = samples[].map!(a => tuple!("sample","f1","f2","f3")(i++,f1(a),f2(a),f3(a))).array;
writeln(arr);

===== output
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(0, 3, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(1, 6, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(2, 9, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(3, 12, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(4, 15, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(5, 18, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(6, 21, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(7, 24, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(8, 27, 0.7, 0.8)
Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(9, 30, 0.7, 0.8)

=============
However, I was trying to use each!, with the intention of then moving to parallel processing by samples blocks. My guess is this would be more efficient than using parallel map or amap, which would parallel process by function application, if I understand correctly.

It isn't clear to me from the examples if something like below can be rewritten to use the chained calls.

foreach(i, ref elem; taskPool.parallel(samples, 100))

December 27, 2015
On 12/27/2015 08:42 AM, Jay Norwood wrote:

> However, I was trying to use each!, with the intention of then moving to
> parallel processing by samples blocks. My guess is this would be more
> efficient than using parallel map or amap, which would parallel process
> by function application, if I understand correctly.

There is also taskPool.asyncBuf but it made your code on the other thread with apply_metrics() even slower.

> It isn't clear to me from the examples if something like below can be
> rewritten to use the chained calls.
>
> foreach(i, ref elem; taskPool.parallel(samples, 100))

parallel() returns struct ParallelForeach, which is not an InputRange. That limits its usefulness. However, each() seems to work with types that provide opApply() (which ParallelForeach does) and the following works (in some cases):

    some.range.chain.parallel.each!(/* ... */);

Ali