I know that e.g. doing this
if (rand() % 2 == 0) value = 0;
else value = (float)rand()/(float)(RAND_MAX/(abs(rand())));
will generate roughly 50% zeroes and 50% other values. But are there other implementations so that I can set the sparsity arbitrarily e.g. to 42% or so.
CodePudding user response:
Yes, you can implement a discrete distribution.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
int percent;
int value;
} pv;
#define Size(x) (sizeof (x) / sizeof *(x))
int main() {
srand((unsigned)time(NULL));
pv pvs[] = {{42, 0}, {58, 1}}; // 42% 0, 58% 1
int v = rand() % 100;
for(int i = 0, x = 0; i < Size(pvs); i) {
x = pvs[i].percent;
if(v < x) {
printf("%d\n", pvs[i].value); // selected
break;
}
}
}
CodePudding user response:
Since C 11, std::bernoulli_distribution
from the <random>
header can be used.
#include <random>
#include <iostream>
int main() {
std::random_device rd;
std::default_random_engine e(rd());
std::bernoulli_distribution d(0.42); // 42% probability of true
std::cout << std::boolalpha;
for (int i = 0; i < 10; i)
std::cout << d(e) << '\n';
return 0;
}
CodePudding user response:
You're getting 50/50 because you're using '%2'.
If you want something like 42 out of 100 values to be non-zero, then all you need is
val = ( rand() % 100 <= 42 ) ? rand() : 0;
If you need 42.5%, for instance, simply use '1000' and '425' instead.