How to set a random matrix in this case? - c

Recently I saw link on this site
Sweeping through a 2d arrays using pointers with boundary conditions
Here, in "answers", is a code of boundary conditions in Ising Model.
This code generate a matrix with all spins up:
for (i=0; i<Lattice_Size; i++) {
for (j=0; j<Lattice_Size; j++) {
*ptr++ = spin_up; // initializing to parallel spins,
// where spin_up is an integer number
// taking value = +1.
}
}
My question is: How one can set up a random configuration (matrix) with random distribution of spin_up / spin_down spins?
I thought it might be done with the help of function random(...), but I figured out that I don't understand well how it works :(

You could use the function rand modulo 2:
srand(time(NULL)) ; // Initialize the rand see
for (i=0; i < Lattice_Size; i++) {
for (j=0; j < Lattice_Size; j++) {
*ptr++ = 1 - 2 * (rand() % 2); // Return either 1 or - 1
}
}
Don't forget to include time.h and stdlib.h.
rand() returns a number in the range between 0 and RAND_MAX
rand() % 2 returns either 0 or 1
2 * (rand() % 2) returns either 0 or 2
1 - 2 * (rand() % 2) returns -1 or 1.
If you are not familiar with it, % is the modulo operator.

Related

How can you make a random number generator that chooses between the number 2 or 3. (not 1,2,3)

Hi I am working on a monty hall generator and in part of my code I need it to generate random number 2 or 3. It cannot be 1,2,3 but the computer needs to select between 2 or 3.
Thanks!
I have tried randomCarDoor = ( rand() % 3 ) + 1; but does not work.
randomCarDoor = ( rand() % 3 ) + 1;
It gives me the number 1,2,3 but I just want 2 and 3
You can use the low order bit of the random value, but it is very risky as some pseudo-random number generators do not provide adequate dispersion on low order bits:
int two_or_three = 2 + rand() % 2;
A much better way is to use the magnitude of the random number which is specified as having a flat distribution:
int two_or_three = 2 + (rand() >= RAND_MAX / 2);
If you want numbers 1 and 3, here is a simple solution for any pair:
int random_value = (rand() < RAND_MAX / 2) ? 1 : 3;
As #Kerrek SB suggest, your formula is: random() % 2 + 2:
random() % 2 ==> Gets [0 or 1]
[0 or 1] + 2 ==> Gets [2 or 3]
A functional code is:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int main()
{
// Declare variables
int i;
int randomNumber;
// Set random seed
srand(time(NULL));
// Get 10 random numbers between 2 and 3
for (i = 0; i < 10; ++i){
randomNumber = rand() % 2 + 2;
printf("Random %d: %d\n", i, randomNumber);
}
// End function
return 0;
}
This is not trivial using rand() since a linear congruential generator typically alternates between odd and even numbers.
So one of the worst things you can do it to use a formula based on rand() % 2.
In this particular case, I suggest you draw based on
n = rand();
and call it 1 if n < RAND_MAX / 2 and 3 otherwise, which you can do with
rand() < RAND_MAX / 2 ? 1 : 3
That might have adequate statistical properties - perhaps some unwanted autocorrelation - but probably no worse than rand() itself.

How to generate random long int in C where every digit is non-zero? Moreover the random numbers are repeating

I am making a library management in C for practice. Now, in studentEntry I need to generate a long int studentID in which every digit is non-zero. So, I am using this function:
long int generateStudentID(){
srand(time(NULL));
long int n = 0;
do
{
n = rand() % 10;
}while(n == 0);
int i;
for(i = 1; i < 10; i++)
{
n *= 10;
n += rand() % 10;
}
if(n < 0)
n = n * (-1); //StudentID will be positive
return n;
}
output
Name : khushit
phone No. : 987546321
active : 1
login : 0
StudentID : 2038393052
Wanted to add another student?(y/n)
I wanted to remove all zeros from it. Moreover, when I run the program the first time the random number will be the same as above, and second time random number is same as past runs like e.g:-
program run 1
StudentID : 2038393052
StudentID : 3436731238
program run 2
StudentID : 2038393052
StudentID : 3436731238
What do I need to fix these problems?
You can either do as gchen suggested and run a small loop that continues until the result is not zero (just like you did for the first digit) or accept a small bias and use rand() % 9 + 1.
The problem with the similar sequences has its reason with the coarse resolution of time(). If you run the second call of the function to fast after the first you get the same seed. You might read this description as proposed by user3386109 in the comments.
A nine-digit student ID with no zeros in the number can be generated by:
long generateStudentID(void)
{
long n = 0;
for (int i = 0; i < 9; i++)
n = n * 10 + (rand() % 9) + 1;
return n;
}
This generates a random digit between 1 and 9 by generating a digit between 0 and 8 with (rand() % 9) and adding 1. There's no need to for loops to avoid zeros.
Note that this does not call srand() — you should only call srand() once in a given program (under normal circumstances). Since a long must be at least 32 bits and a 9-digit number only requires 30 bits, there cannot be overflow to worry about.
It's possible to argue that the result is slightly biassed in favour of smaller digits. You could use a function call to eliminate that bias:
int unbiassed_random_int(int max)
{
int limit = RAND_MAX - RAND_MAX % max;
int value;
while ((value = rand()) >= limit)
;
return value % max;
}
If RAND_MAX is 32767 and max is 9, RAND_MAX % 9 is 7. If you don't ignore the values from 32760 upwards, you are more likely to get a digit in the range 0..7 than you are to get an 8 — there are 3642 ways to each of 0..7 and only 3641 ways to get 8. The difference is not large; it is smaller if RAND_MAX is bigger. For the purposes on hand, such refinement is not necessary.
Slightly modify the order of your original function should perform the trick. Instead of removing 0s, just do not add 0s.
long int generateStudentID(){
srand(time(NULL));
long int n = 0;
for(int i = 0; i < 10; i++)
{
long int m = 0;
do
{
m = rand() % 10;
}while(m == 0);
n *= 10;
n += m;
}
//Not needed as n won't be negative
//if(n < 0)
//n = n * (-1); //StudentID will be positive
return n;
}

Ternary Operator in For Loop causing infinite iterations

I was working on a function to transpose an NxN matrix which is stored in an array of floats. My first implementation seemed to cause the function to loop infinitely and I can't seem to figure out why. Here is the original code:
for(int i = 0; i < numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1; i++)
{
for(int j = i + 1; j < numColumns; j++)
{
//Swap [i,j]th element with [j,i]th element
}
}
However the function never returns. Failing to see the error in my logic I rephrased the expression and now have the following working code:
int middleRow = numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1;
for(int i = 0; i < middleRow; i++)
{
for(int j = i + 1; j < numColumns; j++)
{
//Swap [i,j]th element with [j,i]th element
}
}
Can anybody help explain why the first version does not work but the seemingly equivalent second version does?
As per the operator precedence table, < has higher priority over ?:. You need to use () as required explicitly to enforce the required priority.
Change
for(int i = 0; i < numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1; i++)
to
for(int i = 0; i < ( numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1) ; i++)
Note: Please use the second approach. Much, Much better in readability, maintenance and understanding.
I think there is a problem with the precedence of the operators.
If you want to keep the cluttered first version (which I don't recommend) use parenthesis:
i < (numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1)
Try:
i < ((numRows + 1) / 2)
If numRows is even, it will just be numRows/2. If odd, it will be numRows/2+1.
That will be faster and avoids branching due to the compare (unless you have a n excelent compiler which knows this pattern - unlikely.
You sometimes have to step back to see the whole picture.

Generating a Sparse Matrix in C

Is there a simpler way of generating sparse matrix other than this?
for (i = 0; i < 1000; i++)
{
if (rand() % 3 == 0)
{
array[i] = rand() % 3;
}
else
{
array[i] = ((rand() % 3) - 1);
}
}
Thanks.
I used array for presentational purposes
With a determine how sparse you want it to be.
for (i = 0; i < 1000; i++)
{
if (rand() % a == 0)
{
array[i] = rand() % 100;
}
else
{
array[i] = 0;
}
}
Let t be the target number of non-zero elements in the array, which should be much less than the length of the array for sparseness. I'm assuming your array is of length length. I'm also generating the random indices without the modulus operator to avoid modulo bias.
for (i = 0; i < t; ++i) {
int index = (int) (length * ((double) rand() / (RAND_MAX + 1.0)));
array[index] = i % 2 ? -1 : 1;
}
Note that this may give a few less than t non-zero elements because random numbers can produce duplicates, but that should be rare if it really is sparse, e.g., t < square root of the array length. If you're worried about duplicate randoms making things sparser than you want, you can modify accordingly:
for (i = 0; i < t;) {
int index = (int) (length * ((double) rand() / (RAND_MAX + 1.0)));
if (array[index]) { /* something already at this index */
continue; /* skip incrementing and try again */
}
array[index] = i % 2 ? -1 : 1;
++i;
}
In both cases I'm alternating +/- ones for the non-zero values, but if you want it more random that would be easy to replace the right-hand side of the assignment of array[index].
Finally, I ask your indulgence if I fluffed something on C syntax. My C is about 15 years rusty, but the intent should be clear.

Random Number: either 0 or 1

I've this code:
srand(time(NULL));
int n = rand() % 1 + 0;
printf("%d\n", n);
But, if i put it (notsrand(time(NULL))) in a loop for e.g., it generates only a sequence of 0.
There is another implementation for the random numbers between 0 and 1 or i've forgot something?
If you meant 0 or 1, your % makes some sense, but you meant % 2 (or & 1). Of course, the + 0 is still rather pointless, no idea what you're aiming for there. For an integer result of 0 or 1, just do:
const randomBit = rand() % 2;
The compiler will probably "strength-reduce" that to:
const randomBit = rand() & 1;
Also, make sure you only call srand() once in your program or it won't have the effect you expect.
If you want either 0 or 1, just do
int n = rand() % 2
if what rand returns is even you'll get a 0, and if it's odd you'll get a 1 here.
int n = rand() % 1 + 0;
will produce 0 always as rand() % 1 gives 0 (rand()%a generates number between 0 to a-1).
std::srand(time(0)); //Randomise seed initialisation
for (int rows = 0; rows < n; rows++) {
int randNum = rand() % 2;
}

Resources