问题
Its a small code to generate a random hermitian matrix hermitian matrix.
I have called srand() before every call to rand(). but still no randomness in the output.
I have used c99's complex datatype feature to create a hermitian matrix. I'm not sure where i'm wrong :(
#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>
#include <time.h>
#define MATSIZE 5
#define RAND_RANGE 100
double complex mat[MATSIZE][MATSIZE];
void gen_mat()
{
int i =0,j;
int real;
int img;
for( ;i < MATSIZE; i++)
{
srand(time(NULL));
real = rand()%RAND_RANGE + 1;
srand(time(NULL));
img = rand()%RAND_RANGE + 1;
for(j = MATSIZE; j != i ; j--)
{
mat[i][j] = real + img * I;
mat[j][i] = conj(mat[i][j]);
}
srand(time(NULL));
if(i == j)
mat[i][i] = rand()%RAND_RANGE + 0*I;
}
}
void print_mat()
{
int i,j;
for(i = 0; i < MATSIZE; i++)
{
for(j = 0; j < MATSIZE; j++)
{
printf("%f + %f *i", creal(mat[i][j]), cimag(mat[i][j]));
printf(" ");
}
puts("\n");
}
}
int main()
{
gen_mat();
print_mat();
return 0;
}
sample output
[aft@centos-c physics-numaric]$ ./a.out
66.000000 + 0.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i
67.000000 + -67.000000 *i 66.000000 + 0.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i
67.000000 + 67.000000 *i 67.000000 + -67.000000 *i 66.000000 + 0.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i
67.000000 + 67.000000 *i 67.000000 + -67.000000 *i 67.000000 + -67.000000 *i 66.000000 + 0.000000 *i 67.000000 + 67.000000 *i
67.000000 + 67.000000 *i 67.000000 + -67.000000 *i 67.000000 + -67.000000 *i 67.000000 + -67.000000 *i 66.000000 + 0.000000 *i
EDIT calling srand in main() actually solved the problem. Thank you guys.
[aft@centos-c physics-numaric]$ ./a.out
31.000000 + 0.000000 *i 81.000000 + 75.000000 *i 81.000000 + 75.000000 *i 81.000000 + 75.000000 *i 81.000000 + 75.000000 *i
81.000000 + -75.000000 *i 53.000000 + 0.000000 *i 69.000000 + 57.000000 *i 69.000000 + 57.000000 *i 69.000000 + 57.000000 *i
69.000000 + 57.000000 *i 69.000000 + -57.000000 *i 27.000000 + 0.000000 *i 93.000000 + 11.000000 *i 93.000000 + 11.000000 *i
93.000000 + 11.000000 *i 69.000000 + -57.000000 *i 93.000000 + -11.000000 *i 58.000000 + 0.000000 *i 76.000000 + 78.000000 *i
76.000000 + 78.000000 *i 69.000000 + -57.000000 *i 93.000000 + -11.000000 *i 76.000000 + -78.000000 *i 67.000000 + 0.000000 *i
回答1:
Don't call srand
before every call to rand
. Call it once when your program starts.
回答2:
Don't call srand
inside if the loop. Call it only once.
srand(time(NULL));
for( ;i < MATSIZE; i++)
{
// ... calls to rand()
}
Otherwise you seed the random generator with the same seed (as it is fast enough to get the same time)
BTW, many times I find it very conventional to create an init function for the program / sequence where I initialize many things, including the random generation (e.g. call srand()
)
回答3:
You don't want to seed the random number generator with srand()
every time! Just call it once at the beginning of your program. Then call rand()
to get the next random number.
回答4:
Don't do this:
rand()%RAND_RANGE + 0*I;
, since it will cause the lower values to be oversampled if RAND_RANGE and RAND_MAX+1 don't divide. (which "almost always" is the case)
Also: restarting the generator based on time(NULL) will in most cases restart with exactly the same value, since the granularity of time_t is one second.
Final: rand_max will have at least 15 bits (32K) worth of random. Older systems might actually deliver only 15 bits, with a cycle of 32 K.
UPDATE: this is a snippet from wakkerbot. The urnd() function attempts to return an unbiased value between 0 and range. The test can probably be performed more elegantly.
typedef unsigned long long BigThing;
unsigned int urnd(unsigned int range)
{
static bool flag = FALSE;
if (flag == FALSE) {
#if defined(__mac_os) || defined(DOS)
srand(time(NULL));
#else
srand48(time(NULL));
#endif
}
flag = TRUE;
#if defined(__mac_os) || defined(DOS)
return rand()%range;
#else
if (range <= 1) return 0;
while(1) {
BigThing val, box;
#if WANT_RDTSC_RANDOM
val = rdtsc_rand();
#else
val = lrand48();
#endif
/* we need this to avoid oversampling of the lower values.
* Oversampling the lower values becomes more of a problem if (UNSIGNED_MAX/range) gets smaller
*/
box = val / range;
if ((1+box) *range < range) continue;
return val % range;
}
#endif
}
来源:https://stackoverflow.com/questions/10259028/rand-is-not-returning-random-values