LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Random numbers between -5.0 to +5.0 (https://www.linuxquestions.org/questions/linux-newbie-8/random-numbers-between-5-0-to-5-0-a-809943/)

smp 05-25-2010 02:24 AM

Random numbers between -5.0 to +5.0
 
Hi,

How to create random numbers between -5.0 to +5.0 ?

smp

grail 05-25-2010 02:27 AM

-4.2 does that help?

Without a reference to any language or function I presume you just need some thrown around.

b0uncer 05-25-2010 03:03 AM

If you have a function that creates (pseudo) random numbers in the range 0..1, a crude way is to simply shift the random number by one half (to "center" the distribution), then multiply by 10. A hopefully clarifying example (let's call the random number generating function rand()):

- initially rand() returns something between 0..1
- (rand() - 0,5) is then something between -0,5..0,5
- 10*(rand() - 0,5) is then something between -5..5

This is not a good way, however, if you need "good" random numbers between -5 and 5 (I'd say if it's a school work, that probably is enough, but if it's not, you'll want to see something else). In addition the quality of the random numbers depends on how you actually pull out the initial randon number; typically language built-in functions for this are not your best option. Better would be if you wrote your own pseudo random number algorithm, but it means extra work and considerations.

Note that you'll only get pseudo random numbers, not "real ones". To get good numbers that are more "random" than the typical quick solutions, you'd need to implement some kind of truly random effects into the algorithm, like noise from some physical device.

smp 05-25-2010 03:27 AM

Quote:

This is not a good way, however, if you need "good" random numbers between -5 and 5 (I'd say if it's a school work, that probably is enough, but if it's not, you'll want to see something else). In addition the quality of the random numbers depends on how you actually pull out the initial randon number; typically language built-in functions for this are not your best option. Better would be if you wrote your own pseudo random number algorithm, but it means extra work and considerations.
I am using ran1() function from "Numerical Recipes in C" to generate the random numbers between 0 and 1.

I am using the same trick as you mentioned.

But you said, this is not a good way to create such numbers between -5.0 and +5.0.

What is then the better way?

smp

salasi 05-25-2010 06:56 AM

Quote:

Originally Posted by b0uncer (Post 3980331)

This is not a good way, however, if you need "good" random numbers...

We don't really know what kind of random numbers the OP wants (evenly distributed seems to have been the assumption, but it could be anything else) and what is the intended use.

For example, there have to be doubts about what the last decimal place will do if you multiply by ten? Is that still going to be 'random' or will it always have some particular value? Of course, there are many applications in which this won't be of concern, because you are going to truncate the string to a fewer number of decimal places.

Quote:

What is then the better way?
Can you say what you want to do with the numbers that result from this process?

b0uncer 05-25-2010 04:03 PM

Well you have basically two choices, either use a better random number generator (Numerical Recipes things are generally fine as educational examples, but hardly "good" when compared to commercial options) to get the random numbers between 0 and 1 that you then "scale", or increase the accuracy of the floating-point numbers and operations. The former one is easier to achieve. You can take a look at mathematical computer science articles (the more recent ones may have fresh ideas), random numbers are the subject of such articles every now and then. Another option is to buy a hardware random number generator, which is usually way better than any pseudo random number generating algorithm.

I'll repeat that if you're being academic here, you can well settle with the Numerical Recipes approach (or other such algorithm). Unless it's security related, you'll probably do well with that.

smp 05-25-2010 11:41 PM

Quote:

We don't really know what kind of random numbers the OP wants (evenly distributed seems to have been the assumption, but it could be anything else) and what is the intended use.

For example, there have to be doubts about what the last decimal place will do if you multiply by ten? Is that still going to be 'random' or will it always have some particular value? Of course, there are many applications in which this won't be of concern, because you are going to truncate the string to a fewer number of decimal places.
Yes. I want evenly distributed RNs.
Using ran1() from NR, I generated these following NRs (3rd column) within -0.5 to +0.5. First column is the direct output of ran1(). 2nd column is subtraction of 0.5 from each entry in 1st column. Then each entry in 2nd column is multiplied by 10.


Code:

0.172861        -0.327139        -3.271394
0.680409        0.180409        1.804094
0.917078        0.417078        4.170783
0.917510        0.417510        4.175104
0.766779        0.266779        2.667792
0.648501        0.148501        1.485010
0.334211        -0.165789        -1.657888
0.505953        0.005953        0.059530
0.652182        0.152182        1.521825
0.158174        -0.341826        -3.418264
0.912751        0.412751        4.127514
0.257593        -0.242407        -2.424071
0.810990        0.310990        3.109902
0.267308        -0.232692        -2.326918
0.188872        -0.311128        -3.111279
0.237323        -0.262677        -2.626774
0.312265        -0.187735        -1.877350
0.551604        0.051604        0.516042
0.944883        0.444883        4.448833
0.673464        0.173464        1.734645

The last digits in the numbers (of 3rd column), I suppose, are random.

I want to use these NRs in my current task in a Adaptive Optics simulation. I am working as a scientific assistant in a research institute.

Quote:

Well you have basically two choices, either use a better random number generator (Numerical Recipes things are generally fine as educational examples, but hardly "good" when compared to commercial options) to get the random numbers between 0 and 1 that you then "scale", or increase the accuracy of the floating-point numbers and operations.
My main concern is whether the "scaling thing" i.e. subtract 0.5 and multiply by 10 is "good". In other words, is there any method to produce random numbers between -N to +N DIRECTLY i.e. without using "scaling"?

salasi 05-26-2010 04:17 AM

Quote:

Originally Posted by smp (Post 3981335)
The last digits in the numbers (of 3rd column), I suppose, are random.

There are tests for statistical randomness; as far as I can tell from what you have written the only test that you have applied is "I don't know where those last digits come from".

While I don't know where they come from either, there are a lot of 3s and 4s as terminal digits in that list, and if I thought that might make a difference to what I was ultimately do with the numbers, I'd want to investigate further. Like look at a longer list, and apply a statistical test, rather than just eyeballing the numbers.

The 'clumpiness' might not be true of a longer list. Of course, it might not make a real difference to what you do with the numbers; the rest of us cannot really tell from the information supplied, which was a bit of a 'Seattle Helicopter'.

smp 05-27-2010 12:51 AM

Quote:

Originally Posted by salasi (Post 3981527)
There are tests for statistical randomness; as far as I can tell from what you have written the only test that you have applied is "I don't know where those last digits come from".

While I don't know where they come from either, there are a lot of 3s and 4s as terminal digits in that list, and if I thought that might make a difference to what I was ultimately do with the numbers, I'd want to investigate further. Like look at a longer list, and apply a statistical test, rather than just eyeballing the numbers.

The 'clumpiness' might not be true of a longer list. Of course, it might not make a real difference to what you do with the numbers; the rest of us cannot really tell from the information supplied, which was a bit of a 'Seattle Helicopter'.


okay. I will check.
Thanks.

Regards,
smp

dasy2k1 05-27-2010 07:35 PM

depends what they are for, but for testing system robustness to noise i tend to use octave's rand function to generate me a list of psudo random numbers....

if its for cryptography you want some secure hash function of a truly chaiotic input
suggest a noisy diode, a geiger counter and a lava lamp somwhere in the process

(i belive sun use an array of LDRs pointed at a lava lamp for this)

Greg Marks 08-04-2010 02:25 AM

Here's a little C program that I think does what you want. It requires "sudo apt-get install libbsd-dev"; you also need to install MPFR (http://www.mpfr.org/).

Code:

/*  Generate a random real number  x  in  [0, 1]  with uniform distribution  */
/*  Compile thus:  gcc -o smp smp.c -L/usr/local/lib -lmpfr -lgmp -lbsd  */
/*  Usage:  ./smp N  (where  N  is the desired number of bits of precision)  */
#include <stdio.h>
#include <limits.h>
#include <gmp.h>
#include <mpfr.h>

#define A4R_BOUND 2147483647

main(int argc, char **argv)
{
unsigned long int precision;

printf("\nThis program generates a pseudo-random real number  x  in the\ninterval  [-5, 5]  with uniform probability density function.\n\n");

if (argc == 2)
    {
    precision=atoi(argv[1]);
    }
else
    {
    printf("Input desired number of bits of precision: ");
    scanf("%li", &precision);
    printf("\n");
    }

precision=precision+9;

int j, k, t_2, t;
mpfr_t x, nextbit, one;
/*  Declare MPFR variables.  */
mpfr_init2 (x, precision);
/*  Initialize  x,  set its precision in bits.  */
/*  Note:  1  bit =  0.30102999566398119521373889472449302...  digits.  */
mpfr_init2 (nextbit, precision);
mpfr_init2 (one, precision);
mpfr_set_ui (one, 1, GMP_RNDN);
/*  Set  one = 1.  */
mpfr_set_ui (x, 0, GMP_RNDN);
/*  Set  x = 0.  */

for (j=1; j<=precision; j++) {
    do {
        k = arc4random();
        t_2 = abs(k);
        t = t_2 % 2;} while ((k < -(A4R_BOUND  - (A4R_BOUND % 2))) || (k > A4R_BOUND  - (1 + (A4R_BOUND % 2))));
        /*  The variable  t  is randomly  0  or  1.  */
        if (t==1) {
            mpfr_div_2ui (nextbit, one, j, GMP_RNDN);
            /*  Set  nextbit = 1/2^j.  */
            mpfr_add (x, x, nextbit, GMP_RNDN);
            /*  x = x + nextbit.  */
            };
        };
mpfr_mul_ui (x, x, 10, GMP_RNDN);
/*  x = x * 10.  */
mpfr_sub_ui (x, x, 5, GMP_RNDN);
/*  x = x - 5.  */
mpfr_printf ("%.*Rf\n", precision-8, x);

/*  MPFR programs should always end by clearing variables and cache:  */
mpfr_clear (x);
mpfr_free_cache ();

return 0;
}


smp 08-05-2010 12:35 AM

Quote:

Here's a little C program that I think does what you want. It requires "sudo apt-get install libbsd-dev"; you also need to install MPFR (http://www.mpfr.org/).
I have not understood what "sudo apt-get install libbsd-dev" does?
Will you please explain this in detail (each word in this command)?
I am not expert in linux.

regards,

Greg Marks 08-17-2010 06:57 PM

Linux provides a useful resource for learning answers to questions of this sort. From the command line type:

Quote:

man sudo
and then

Quote:

man apt-get
(The word "install" will be explained in the man page of "apt-get.") To read details of the package "libbsd-dev," type "libbsd-dev" into Google.

I hope this helps!


All times are GMT -5. The time now is 09:16 AM.