1

How to generate 100 randoms float between -1 and 1 with the main distriburion between -0.1 to 0.1 (90 % of float numbers must be between -0.1 to 0.1). Currently I use which is not exactly what i want

for (int counter = 0; counter < 100; counter++)
{
   randomnum = 0f;
   randomnum = Convert.ToSingle(randomvalues.NextDouble() / 10);
   storerandomvalues1[counter] = randomnum;
}

Any idea?

Calum
  • 1,889
  • 2
  • 18
  • 36
user3585203
  • 15
  • 1
  • 3
  • What sort of a distribution do you want outside of that range? Do you want an even distribution within -0.1 to 0.1? We need a lot more information here. – Sean Duggan May 16 '14 at 13:34
  • What are you having problems with? – Sayse May 16 '14 at 13:34
  • Are you going for something like a normal distribution, or even distributions within each subrange? – Tim S. May 16 '14 at 13:35
  • 1
    [This may be related](http://stackoverflow.com/q/218060/335858) (not a duplicate, though). – Sergey Kalinichenko May 16 '14 at 13:35
  • I mean 90 perecnt of generated float must be in the range of -0.1 to 0.1 @TimS. – user3585203 May 16 '14 at 13:37
  • @dasblinkenlight, it seems like the answer by Superbest is pretty close to being exactly what the OP is looking for eh? – Mike Perrenoud May 16 '14 at 13:38
  • 90% exactly or at least 90% must be in that range? – faby May 16 '14 at 13:39
  • @user3585203 Because you are generating random numbers you have to realize that your algorithm can be constructed to give you 90% of the numbers between -0.1 and 0.1, *BUT* on any given run of your program you might not actually have 90% of the numbers between -0.1 and 0.1. This is how distributions and randoms work. Just something important to know! – drew_w May 16 '14 at 13:46
  • 1
    Your question is underdefined. There are many different distributions fitting your requirements. – CodesInChaos May 16 '14 at 13:58
  • Expanding on @CodesInChaos comment, there are an infinite number of possible answers to your question because you haven't given any information about how you want the outcomes distributed. Absolutely any function which is strictly positive and has finite area over the range -0.1 to 0.1 can be scaled to have area 1 and will be a mathematically valid distribution. Ditto for functions from -1 and -0.1, and 0.1 to 1. Generate values from the first function with probability 0.9, and from the other two with any mix of probabilities that total to 0.1, and your stated requirements have been met. – pjs May 16 '14 at 17:41
  • Have you looked at the [System.Security.Cryptography namespace](http://msdn.microsoft.com/library/system.security.cryptography.aspx "System.Security.Cryptography Namespace")? – Paulo Morgado May 17 '14 at 11:43

4 Answers4

3

This should work. It generates one random number to choose whether you're in the range -0.1,0.1 and then a second which is expanded to the actual range you want it in. You could do it with just one random double, but that would make it easier to get the code wrong, and harder to read (all for a tiny performance improvement).

for (var counter = 0; counter < 100; counter++)
{
    int selector = randomvalues.Next(10); // 0 <= selector < 10
    double randomnum;
    if (selector < 9)
    {
        randomnum = randomvalues.NextDouble() * 0.2 - 0.1;
    }
    else
    {
        randomnum = randomvalues.NextDouble() * 1.8 - 0.9;
        randomnum += Math.Sign(randomnum) * 0.1;
    }
    storerandomvalues1[counter] = (float)randomnum;
}
Tim S.
  • 55,448
  • 7
  • 96
  • 122
0

As I said in a comment, there are an infinite number of possible solutions. Two possible solutions follow:

  1. A Normal (aka Gaussian) distribution with a mean of 0 and a standard deviation of 0.06079 will have 90% of its outcomes between -0.1 and +0.1, so generate a standard normal and multiply it by 0.06079. Technically you should check whether the absolute value exceeds 1, but that corresponds to getting outcomes at 16 sigma -- it's just not going to happen.

  2. However, you might not like solution that because it won't span the entire range in practice. A variant which will is to generate X as described in the prior paragraph, and if X < -0.1, replace it with a Uniform(-1, -0.1). Similarly, if X > 0.1, replace it with a Uniform(0.1, 1).

I implemented both of these, generated 100,000 values, and here are the histograms:

Histograms and quantiles for two approaches

Note that the 5th and 95th quantiles are -0.0998 and +0.09971, respectively, effectively -0.1 and +0.1 to within sampling error.

pjs
  • 18,696
  • 4
  • 27
  • 56
-1

use log function, Generate floats between 1 and 10, then take the log base 10 of the result. then randomly change the sign.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • What distribution do you suggest for the floats, because it doesn't seem to give 90% below 0.1 for a uniform distribution. – Rawling May 16 '14 at 14:19
  • I was thinking if the random floats generated in step 1 are evenly distributed between 1 and 10, then taking the log base 10 should cause all the values that were between 1 and 9 (which should be 90% of them) to be between 0 and .1, and all the values between 9 and 10 should end up being between .1 and .999999 - You may have to fiddle with the numbers a bit to get this to align properly, but the concept should work. Basically you need a function that reshapes an even distribution of values into a distribution with a specific shape. And the Log function is the shape you're after. – Charles Bretana May 16 '14 at 14:33
  • Log's the opposite of the shape we're after, I think. log base 10 of 1.3 is already greater than 0.1. – Rawling May 16 '14 at 14:38
-3

Try this, it should work...

   Random rnd = new Random();
    for (int counter = 0; counter < 100; counter++)
    {
        storerandomvalues1[counter]=(2*rnd.NextDouble())-1; // Exact Sample() is protected so u can use NextDouble()
    }
angel
  • 322
  • 1
  • 7
  • 2
    This ignores the request for a normal distribution "90% of the numbers between -0.1 and 0.1" – drew_w May 16 '14 at 13:42
  • Isn't `Sample()` marked as `protected`? http://msdn.microsoft.com/en-us/library/system.random.sample.aspx – Thomas Weller May 16 '14 at 13:43
  • rnd.Sample give a number between 0 and 1 /////// 2 * rnd.Sample() give a number between 0 and 2 //////// 2 * rnd.Sampe()-1 Will give a number between -1 and 1 – angel May 16 '14 at 13:46
  • if you don't want 100 numbers between 0 and 1, My answer is wrong... So Maybe i didn't understand your question, it's possible because I don't speak english very well :-D – angel May 16 '14 at 13:51