Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!

Notices

Welcome to LinuxQuestions.org, a friendly and active Linux Community.

You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!

Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.

If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.

Having a problem logging in? Please visit this page to clear all LQ-related cookies.

Introduction to Linux - A Hands on Guide

This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.

Click Here to receive this Complete Guide absolutely free.

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.

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.

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?

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.

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.

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"?

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'.

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'.

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)

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;
}

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.

LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.