www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Generate array of random values

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I'm currently using this:

import std.algorithm;
import std.array;
import std.random;
import std.range;

void main()
{
    auto arr2 = array(map!( (int){ return uniform(0, 1024); })(iota(0, 1024)));
}

Is there a simpler way to do get an array of random values?
Jul 30 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 void main()
 {
     auto arr2 = array(map!( (int){ return uniform(0, 1024); })(iota(0, 1024)));
 }
 
 Is there a simpler way to do get an array of random values?
If you want a single expression you are allowed to write a bit shorter code: auto arr2 = array(map!((int){ return uniform(0, 1024); })(iota(1024))); Once we get amap/afilter added to Phobos (http://d.puremagic.com/issues/show_bug.cgi?id=5756 ) the code gets a bit simpler: auto arr2 = amap!((int){ return uniform(0, 1024); })(iota(1024)); amap/afilter are not orthogonal, but this is acceptable for practicality (and done in all the languages I know), because in D arrays are much more commonly useful than lazy ranges. I have also proposed a N dimensional table() function to be added to Phobos. With it the code gets simple (Mathematica has a similar function): auto arr2 = table!q{ uniform(0, 1024) }(1024); In Python3 you use a list (array) comp: lst = [randrange(1024) for _ in range(1024)] Unfortunately often the "simpler way" in D is to use an imperative programming style. Bye, bearophile
Jul 30 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Yeah I really like Python's list comprehensions. That's something I'll
always miss in D.
Jul 30 2011
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 30 Jul 2011 11:10:38 -0400, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 I'm currently using this:

 import std.algorithm;
 import std.array;
 import std.random;
 import std.range;

 void main()
 {
     auto arr2 = array(map!( (int){ return uniform(0, 1024); })(iota(0,  
 1024)));
 }

 Is there a simpler way to do get an array of random values?
I think that an infinite range which returns random numbers should be a phobos-declared type... If it's not, it should be. -Steve
Aug 01 2011
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 01.08.2011 18:05, Steven Schveighoffer wrote:
 On Sat, 30 Jul 2011 11:10:38 -0400, Andrej Mitrovic 
 <andrej.mitrovich gmail.com> wrote:

 I'm currently using this:

 import std.algorithm;
 import std.array;
 import std.random;
 import std.range;

 void main()
 {
     auto arr2 = array(map!( (int){ return uniform(0, 1024); 
 })(iota(0, 1024)));
 }

 Is there a simpler way to do get an array of random values?
I think that an infinite range which returns random numbers should be a phobos-declared type... If it's not, it should be.
It is, the following e.g. prints 10 random integers: import std.random, std.algorithm, std.stdio, std.range; void main() { Xorshift rng; rng.seed(unpredictableSeed); writeln(take(rng, 10)); } -- Dmitry Olshansky
Aug 01 2011
prev sibling next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 7/30/11 5:10 PM, Andrej Mitrovic wrote:
 Is there a simpler way to do get an array of random values?
If you don't need the random numbers to be in a certain range, you could use array(take(rndGen(), 1024)) – if you do need a limit, that would be array(map!"a % 1024"(take(rndGen(), 1024))). David
Aug 01 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
David Nadlinger:

 if you do need a limit, that would be 
 array(map!"a % 1024"(take(rndGen(), 1024))).
% doesn't give an uniform distribution. Bye, bearophile
Aug 01 2011
parent reply David Nadlinger <see klickverbot.at> writes:
On 8/1/11 8:55 PM, bearophile wrote:
 David Nadlinger:
 array(map!"a % 1024"(take(rndGen(), 1024))).
% doesn't give an uniform distribution.
I'd argue it does with 1024… ;) David
Aug 01 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Actually I don't really need *uniform* distribution, it's just that
when porting C code to D I didn't find any obvious random()/rnd()
functions, and uniform seemed to be the closest thing without having
to mess around with a bunch of randomization parameters which I don't
care about.

I don't see how we can claim D to be an elegant language with this mess:
array(map!"a % 1024"(take(rndGen(), 1024)))

That's just damn *horrible*.
Aug 01 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
I'm barely following this thread, but why not:

===
import std.random;
void main() {
    int[] arr;
    foreach(i; 1 .. 100)
         arr ~= uniform(0, 1024);
}
===

?
Aug 01 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/1/11, Adam D. Ruppe <destructionator gmail.com> wrote:
 I'm barely following this thread, but why not:

 ===
 import std.random;
 void main() {
     int[] arr;
     foreach(i; 1 .. 100)
          arr ~= uniform(0, 1024);
 }
 ===

 ?
Ah but nearly every initialization can be converted to a foreach loop. But I'm trying to avoid that and use a simple expression instead. :)
Aug 01 2011
prev sibling next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 01.08.2011 23:43, Andrej Mitrovic wrote:
 Actually I don't really need *uniform* distribution, it's just that
 when porting C code to D I didn't find any obvious random()/rnd()
 functions, and uniform seemed to be the closest thing without having
 to mess around with a bunch of randomization parameters which I don't
 care about.

 I don't see how we can claim D to be an elegant language with this mess:
 array(map!"a % 1024"(take(rndGen(), 1024)))

 That's just damn *horrible*.
Dunno maybe it's only me, but some years ago when I used C++98 & STL extensively I would find this line a very simple and clean solution. Now time is changing and so on... A thought - would amap as a shorthand for array(map... float your boat? One pair of parens off. -- Dmitry Olshansky
Aug 01 2011
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 On 01.08.2011 23:43, Andrej Mitrovic wrote:
 Actually I don't really need *uniform* distribution, it's just that
 when porting C code to D I didn't find any obvious random()/rnd()
 functions, and uniform seemed to be the closest thing without having
 to mess around with a bunch of randomization parameters which I don't
 care about.
 
 I don't see how we can claim D to be an elegant language with this mess:
 array(map!"a % 1024"(take(rndGen(), 1024)))
 
 That's just damn *horrible*.
Dunno maybe it's only me, but some years ago when I used C++98 & STL extensively I would find this line a very simple and clean solution. Now time is changing and so on... A thought - would amap as a shorthand for array(map... float your boat? One pair of parens off.
Yeah. I confess that I don't see much ugly in that solution. It wouldn't hurt my feelings any to have a cleaner solution, but array(map!"a % 1024"(take(rndGen(), 1024))); seems fine to me. But maybe I'm just too used to the STL and std.algorithm. Regardless, it's _way_ cleaner than what you can achieve in C++98 trying to do the same thing. - Jonathan M Davis
Aug 01 2011
prev sibling parent reply Pelle <pelle.mansson gmail.com> writes:
On Mon, 01 Aug 2011 21:43:13 +0200, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 Actually I don't really need *uniform* distribution, it's just that
 when porting C code to D I didn't find any obvious random()/rnd()
 functions, and uniform seemed to be the closest thing without having
 to mess around with a bunch of randomization parameters which I don't
 care about.

 I don't see how we can claim D to be an elegant language with this mess:
 array(map!"a % 1024"(take(rndGen(), 1024)))

 That's just damn *horrible*.
If we ever get UFCS that'd be rndGen().take(1024).map!"a % 1024"().array() Which is a lot better :--) Without UFCS, well, how would you want it to look? How does it look in other languages?
Aug 02 2011
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/2/11, Pelle <pelle.mansson gmail.com> wrote:
 Without UFCS, well, how would you want it to look?
Maybe.. auto max = 1024; auto len = 1024; arr = rndRange(max)[0..len]; IOW, using the slice operator instead of a call to array().
Aug 02 2011
next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 02.08.2011 16:08, Andrej Mitrovic wrote:
 On 8/2/11, Pelle<pelle.mansson gmail.com>  wrote:
 Without UFCS, well, how would you want it to look?
Maybe.. auto max = 1024; auto len = 1024; arr = rndRange(max)[0..len]; IOW, using the slice operator instead of a call to array().
It could be done , but IMO a lot of generic code would totally expect slice to 1. return the same type as the range itself (or 100% compatible) 2. most of the time not to allocate -- Dmitry Olshansky
Aug 02 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Woops you're right about the range type being returned.

I guess this is the next best thing:

arr = array(rndRange(max, len));
Aug 02 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 Maybe..
 
 auto max = 1024;
 auto len = 1024;
 
 arr = rndRange(max)[0..len];
In my opinion that's not general enough for Phobos, see the N dimensional table() I have explained here: auto arr = table!q{ uniform(0, 1024) }(1024); http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=28543 Bye, bearophile
Aug 02 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
David Nadlinger:

 I'd argue it does with 1024… ;)
Right, I am sorry :-) Bye, bearophile
Aug 01 2011
prev sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Andrej Mitrovic Wrote:

 I'm currently using this:
 
 import std.algorithm;
 import std.array;
 import std.random;
 import std.range;
 
 void main()
 {
     auto arr2 = array(map!( (int){ return uniform(0, 1024); })(iota(0, 1024)));
 }
 
 Is there a simpler way to do get an array of random values?
Untested: auto arr = new int[1024]; fill(arr, uniform(0, 1024));
Aug 01 2011
parent reply David Nadlinger <see klickverbot.at> writes:
On 8/2/11 3:40 AM, Jesse Phillips wrote:
 Andrej Mitrovic Wrote:
 Is there a simpler way to do get an array of random values?
Untested: auto arr = new int[1024]; fill(arr, uniform(0, 1024));
This does a great job of creating an array containing the same random value 1024 times. ;) David
Aug 01 2011
parent reply Jesse Phillips <jessekphillips+d gmail.com> writes:
On Tue, 02 Aug 2011 03:48:03 +0200, David Nadlinger wrote:

 On 8/2/11 3:40 AM, Jesse Phillips wrote:
 Andrej Mitrovic Wrote:
 Is there a simpler way to do get an array of random values?
Untested: auto arr = new int[1024]; fill(arr, uniform(0, 1024));
This does a great job of creating an array containing the same random value 1024 times. ;) David
Fine, let me provide a tested one: import std.algorithm; import std.array; import std.random; import std.range; void main() { auto arr = new int[1024]; fill(arr, randomCover(iota(0,1024), rndGen)); } Knew I had done something with fill before.
Aug 01 2011
parent David Nadlinger <see klickverbot.at> writes:
On 8/2/11 6:42 AM, Jesse Phillips wrote:
      auto arr = new int[1024];
      fill(arr, randomCover(iota(0,1024), rndGen));
Note that this produces a random permutation of the numbers 0 to 1023, which may or may not be what you want. David
Aug 02 2011