Thread overview | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 19, 2022 automate tuple creation | ||||
---|---|---|---|---|
| ||||
so I have this code below, that creates an array of tuples. but instead of hardcoding 5 tuples (or hardcoding any amount of tuples), what I really want to do is automate the creation of how-ever-many tuples I ask for: i.e. instead of calling this: createBoolMatrix(mArrBool); I would call something like this: createBoolMatrix(mArrBool,5); // create an array of 5 typles. Some ideas about direction would be welcome ;-) // --- module test; import std.stdio; import std.range; import std.traits; import std.random; @safe: void main() { uint[][] mArrBool; createBoolMatrix(mArrBool); process(mArrBool); } void process(T)(const ref T t) if (isForwardRange!T && !isInfinite!T) { t.writeln; // sample output -> [[0, 1], [1, 0], [1, 1], [1, 1], [1, 1]] } void createBoolMatrix(ref uint[][] m) { auto rnd = Random(unpredictableSeed); // btw. below does register with -profile=gc m = [ [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd), [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd), [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd), [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd), [cast(uint)rnd.dice(0.6, 1.4), cast(uint)rnd.dice(0.4, 1.6)].randomShuffle(rnd) ]; } // -- |
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to forkit | On Wednesday, 19 January 2022 at 21:59:15 UTC, forkit wrote:
>
oh. that randomShuffle was unnecessary ;-)
|
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to forkit | On Wed, Jan 19, 2022 at 09:59:15PM +0000, forkit via Digitalmars-d-learn wrote: > so I have this code below, that creates an array of tuples. > > but instead of hardcoding 5 tuples (or hardcoding any amount of tuples), what I really want to do is automate the creation of how-ever-many tuples I ask for: > > i.e. > > instead of calling this: createBoolMatrix(mArrBool); > I would call something like this: createBoolMatrix(mArrBool,5); // > create an array of 5 typles. Why can't you just use a loop to initialize it? uint[][] createBoolMatrix(size_t n) { auto result = new uint[][n]; // allocate outer array foreach (ref row; result) { row = new uint[n]; // allocate inner array foreach (ref cell; row) { cell = cast(uint) rnd.dice(0.6, 1.4); } } return result; } Or, if you wanna use those new-fangled range-based idioms: uint[][] createBoolMatrix(size_t n) { return iota(n) .map!(i => iota(n) .map!(j => cast(uint) rnd.dice(0.6, 1.4)) .array) .array; } T -- Verbing weirds language. -- Calvin (& Hobbes) |
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to forkit | On 1/19/22 13:59, forkit wrote: > void createBoolMatrix(ref uint[][] m) > { > auto rnd = Random(unpredictableSeed); That works but would be unnecessarily slow and be against the idea of random number generators. The usual approach is, once you have a randomized sequence, you just continue using it. For example, I move rnd to module scope and initialize it once. Random rnd; shared static this() { rnd = Random(unpredictableSeed); } auto randomValue() { return cast(uint)rnd.dice(0.6, 1.4); } // Returning a dynamically allocated array looks expensive // here. Why not use a struct or std.typecons.Tuple instead? auto randomTuple() { return [ randomValue(), randomValue() ]; } void createBoolMatrix(ref uint[][] m, size_t count) { import std.algorithm : map; import std.range : iota; m = count.iota.map!(i => randomTuple()).array; } Ali |
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 1/19/22 14:33, Ali Çehreli wrote: > Random rnd; > > shared static this() { > rnd = Random(unpredictableSeed); > } But that's a mistake: If rnd is thread-local like that, it should be initialized in a 'static this' (not 'shared static this'). Otherwise, only the main thread's 'rnd' would be randomized, which is the only thread that executes 'shared static this' blocks. Ali |
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wed, Jan 19, 2022 at 02:33:02PM -0800, Ali Çehreli via Digitalmars-d-learn wrote: [...] > // Returning a dynamically allocated array looks expensive // here. Why not use a struct or std.typecons.Tuple instead? Premature optimization. ;-) There's nothing wrong with allocating an array. If you're worried about memory efficiency, you could allocate the entire matrix in a single block and just assemble slices of it in the outer block, like this: uint[][] createBoolMatrix(size_t count) { auto buffer = new uint[count*count]; return iota(count).map!(i => buffer[count*i .. count*(i+1)]) .array; } This lets you do only 2 GC allocations instead of (1+count) GC allocations. May help with memory fragmentation if `count` is large and you create a lot of these things. But I honestly wouldn't bother with this unless your memory profiler is reporting a problem in this aspect of your program. It just adds complexity to your code (== poorer long-term maintainability) for meager benefits. T -- What do you call optometrist jokes? Vitreous humor. |
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Wednesday, 19 January 2022 at 22:35:58 UTC, Ali Çehreli wrote:
>
so I combined ideas from all responses:
// --
module test;
import std.stdio : writeln;
import std.range : iota, isForwardRange, hasSlicing, hasLength, isInfinite, array;
import std.random : Random, unpredictableSeed, dice;
import std.algorithm : map;
@safe:
Random rnd;
static this()
{
rnd = Random(unpredictableSeed);
}
void main()
{
uint[][] mArrBool;
// e.g: create a matrix consisting of 5 tuples, with each tuple containing 3 random bools (0 or 1)
createBoolMatrix(mArrBool,5, 2);
process(mArrBool);
}
void createBoolMatrix(ref uint[][] m, size_t numberOfTuples, size_t numberOfBoolsInTuple)
{
m = iota(numberOfTuples)
.map!(i => iota(numberOfBoolsInTuple)
.map!(numberOfBoolsInTuple => cast(uint) rnd.dice(0.6, 1.4))
.array).array;
}
void process(T)(const ref T t) if (isForwardRange!T && hasSlicing!T && hasLength!T && !isInfinite!T)
{
t.writeln;
}
//--
|
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to forkit | On Wednesday, 19 January 2022 at 23:22:17 UTC, forkit wrote:
>
oops
// e.g: create a matrix consisting of 5 tuples, with each tuple containing 3 random bools (0 or 1)
createBoolMatrix(mArrBool,5, 3);
|
January 19, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 1/19/22 15:21, H. S. Teoh wrote: > On Wed, Jan 19, 2022 at 02:33:02PM -0800, Ali Çehreli via Digitalmars-d-learn wrote: > [...] >> // Returning a dynamically allocated array looks expensive >> // here. Why not use a struct or std.typecons.Tuple instead? > > Premature optimization. ;-) Not in this case because I am pointing at premature pessimization. :) There is no reason to use two-element dynamic arrays when uint[2], Tuple!(uint, uint), and structs are available. > There's nothing wrong with allocating an > array. Agreed. Ali |
January 20, 2022 Re: automate tuple creation | ||||
---|---|---|---|---|
| ||||
Posted in reply to forkit | On Wednesday, 19 January 2022 at 21:59:15 UTC, forkit wrote: > so at the moment i can get a set number of tuples, with a set number of bool values contained within each tuple. e.g. createBoolMatrix(mArrBool,3, 2); [[1, 0], [1, 1], [1, 0]] my next challenge (more for myself, but happy for input).. is to enhance this to an return an associative array: e.g createBoolAssociativeMatrix(mArrBool,3, 2); [ [1000:[1, 0]], [1001:[1, 1]], [1001:[1, 0]]] where 1000 is some random id... |
Copyright © 1999-2021 by the D Language Foundation