libdspl-2.0
Библиотека алгоритмов цифровой обработки сигналов
Генерация псевдослучайных чисел

Структуры данных

struct  random_t
 Структура параметров датчиков псевдослучайных чисел. Подробнее...
 

Функции

int random_init (random_t *prnd, int type, void *seed)
 Инициализация датчиков псевдослучайных чисел. Подробнее...
 
int randb (double *x, int n, random_t *prnd)
 Генерация бинарного униполярного [0, 1] псевдослучайного вектора Подробнее...
 
int randb2 (double *x, int n, random_t *prnd)
 Генерация бинарного биполярного [-1, 1] псевдослучайного вектора Подробнее...
 
int randi (int *x, int n, int start, int stop, random_t *prnd)
 Генерация целочисленного вектора равномерно распределенных псевдослучайных чисел. Подробнее...
 
int randn (double *x, int n, double mu, double sigma, random_t *prnd)
 Генерация вектора нормально распределенных псевдослучайных чисел. Подробнее...
 
int randu (double *x, int n, random_t *prnd)
 Генерация вектора равномерно-распределенных в интервале от 0 до 1 псевдослучайных чисел. Подробнее...
 

Подробное описание

В данном разделе описаны функции генерации псевдослучайных чисел с использованием различных датчиков.

Функции

◆ randb()

int randb ( double *  x,
int  n,
random_t prnd 
)

Генерация бинарного униполярного [0, 1] псевдослучайного вектора


Функция генерирует униполярный псевдослучайный вектор, каждый элемент которого принимает равновероятное значение 0 или 1.

Аргументы
[in,out]x

Указатель на вектор случайных бинарных чисел.
Размер вектора [n x 1].
Память должна быть выделена.

Аргументы
[in]nРазмер вектора x.

[in]prndУказатель на структуру random_t параметров датчиков псевдослучайных чисел.
Структура должна быть предварительно заполнена функцией random_init.
Данный указатель может быть NULL, тогда будет использоваться встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд, например в криптографии, данный режим использовать не рекомендуется. Нет гарантии в качестве произведенной случайной последовательности если параметр prnd задан как NULL.

Возвращает
RES_OK — вектор целых псевдослучайных чисел рассчитан успешно.
В противном случае код ошибки.

Пример использования функции:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 100
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handles */
random_t rnd = {0}; /* random structure */
hdspl = dspl_load(); /* Load DSPL function */
double x[N];
int err;
err = random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
if(err != RES_OK)
goto exit_label;
err = randb(x, N, &rnd);
if(err != RES_OK)
goto exit_label;
writetxt(x, NULL, N, "dat/randb_mrg32k3a.txt");
err = randb2(x, N, &rnd);
if(err != RES_OK)
goto exit_label;
writetxt(x, NULL, N, "dat/randb2_mrg32k3a.txt");
/***************************************************************************/
/* plotting by GNUPLOT */
/***************************************************************************/
/* Create window plot */
err = gnuplot_create(argc, argv, 820, 320, "img/randb_test.png", &hplot);
if(err != RES_OK)
goto exit_label;
gnuplot_cmd(hplot, "set xlabel 'x'");
gnuplot_cmd(hplot, "set ylabel 'y'");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set yrange[-1.2:1.2]");
gnuplot_cmd(hplot, "set title 'randb, randb2'");
gnuplot_cmd(hplot, "plot 'dat/randb_mrg32k3a.txt' with lines, \\");
gnuplot_cmd(hplot, " 'dat/randb2_mrg32k3a.txt' with lines");
exit_label:
printf("Error code: %x\n", err);
if(hplot)
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Программа рассчитывает униполярный [0, 1] и биполярный [-1, 1] бинарные псевдослучайные векторы.

В результате выполнения программы можно увидеть график:

randb_test.png
Автор
Бахурин Сергей. www.dsplib.org

См. определение в файле randgen.c строка 71

◆ randb2()

int randb2 ( double *  x,
int  n,
random_t prnd 
)

Генерация бинарного биполярного [-1, 1] псевдослучайного вектора


Функция генерирует биполярный псевдослучайный вектор, каждый элемент которого принимает равновероятное значение -1 или 1.

Аргументы
[in,out]x

Указатель на вектор случайных бинарных чисел.
Размер вектора [n x 1].
Память должна быть выделена.

Аргументы
[in]nРазмер вектора x.

[in]prndУказатель на структуру random_t параметров датчиков псевдослучайных чисел.
Структура должна быть предварительно заполнена функцией random_init.
Данный указатель может быть NULL, тогда будет использоваться встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд, например в криптографии, данный режим использовать не рекомендуется. Нет гарантии в качестве произведенной случайной последовательности если параметр prnd задан как NULL.

Возвращает
RES_OK — вектор целых псевдослучайных чисел рассчитан успешно.
В противном случае код ошибки.

Пример использования функции:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 100
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handles */
random_t rnd = {0}; /* random structure */
hdspl = dspl_load(); /* Load DSPL function */
double x[N];
int err;
err = random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
if(err != RES_OK)
goto exit_label;
err = randb(x, N, &rnd);
if(err != RES_OK)
goto exit_label;
writetxt(x, NULL, N, "dat/randb_mrg32k3a.txt");
err = randb2(x, N, &rnd);
if(err != RES_OK)
goto exit_label;
writetxt(x, NULL, N, "dat/randb2_mrg32k3a.txt");
/***************************************************************************/
/* plotting by GNUPLOT */
/***************************************************************************/
/* Create window plot */
err = gnuplot_create(argc, argv, 820, 320, "img/randb_test.png", &hplot);
if(err != RES_OK)
goto exit_label;
gnuplot_cmd(hplot, "set xlabel 'x'");
gnuplot_cmd(hplot, "set ylabel 'y'");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set yrange[-1.2:1.2]");
gnuplot_cmd(hplot, "set title 'randb, randb2'");
gnuplot_cmd(hplot, "plot 'dat/randb_mrg32k3a.txt' with lines, \\");
gnuplot_cmd(hplot, " 'dat/randb2_mrg32k3a.txt' with lines");
exit_label:
printf("Error code: %x\n", err);
if(hplot)
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Программа рассчитывает униполярный [0, 1] и биполярный [-1, 1] бинарные псевдослучайные векторы.

В результате выполнения программы можно увидеть график:

randb_test.png
Автор
Бахурин Сергей. www.dsplib.org

См. определение в файле randgen.c строка 98

◆ randi()

int randi ( int *  x,
int  n,
int  start,
int  stop,
random_t prnd 
)

Генерация целочисленного вектора равномерно распределенных псевдослучайных чисел.


Функция генерирует псевдослучайный вектор целых чисел в диапазоне от start до stop включительно.

Аргументы
[in,out]x

Указатель на вектор случайных чисел.
Размер вектора [n x 1].
Память должна быть выделена.

Аргументы
[in]nРазмер вектора x.

[in]startНачало диапазона целых чисел.

[in]stopКонец диапазона целых чисел.

[in]prndУказатель на структуру random_t параметров датчиков псевдослучайных чисел.
Структура должна быть предварительно заполнена функцией random_init.
Данный указатель может быть NULL, тогда будет использоваться встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд, например в криптографии, данный режим использовать не рекомендуется. Нет гарантии в качестве произведенной случайной последовательности если параметр prnd задан как NULL.

Возвращает
RES_OK — вектор целых псевдослучайных чисел рассчитан успешно.
В противном случае код ошибки.

Пример использования функции:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 1000
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handles */
random_t rnd = {0}; /* random structure */
hdspl = dspl_load(); /* Load DSPL function */
int x[N];
int err;
err = random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
if(err != RES_OK)
goto exit_label;
err = randi(x, N, -4, 3, &rnd);
if(err != RES_OK)
goto exit_label;
/* Save to file */
err = writetxt_int(x, NULL, N, "dat/randi_mrg32k3a.txt");
if(err != RES_OK)
goto exit_label;
/***************************************************************************/
/* plotting by GNUPLOT */
/***************************************************************************/
/* Create window plot */
err = gnuplot_create(argc, argv, 820, 320, "img/randi_test.png", &hplot);
if(err != RES_OK)
goto exit_label;
gnuplot_cmd(hplot, "set xlabel 'n'");
gnuplot_cmd(hplot, "set ylabel 'x(n)'");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set yrange[-5:4]");
gnuplot_cmd(hplot, "set title 'randi example'");
gnuplot_cmd(hplot, "plot 'dat/randi_mrg32k3a.txt' with impulses");
exit_label:
printf("Error code = 0x%.8x\n", err);
if(hplot)
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Программа рассчитывает целочисленный вектор псевдослучайных чисел в диапазоне [-4, 3].

В результате выполнения программы можно увидеть график:

randi_test.png
Автор
Бахурин Сергей. www.dsplib.org

См. определение в файле randgen.c строка 181

◆ randn()

int randn ( double *  x,
int  n,
double  mu,
double  sigma,
random_t prnd 
)

Генерация вектора нормально распределенных псевдослучайных чисел.


Функция использует преобразование Бокса-Мюллера для приведения

равномерно-распределенных псевдослучайных чисел к нормальному распределению с математическим ожиданием $\mu$ и средневадратическим отклонением $\sigma$.

Аргументы
[in,out]x

Указатель на вектор случайных чисел.
Размер вектора [n x 1].
Память должна быть выделена.

Аргументы
[in]nРазмер вектора случайных чисел.

[in]muМатематическое ожидание $\mu$.

[in]sigmaCредневадратическое отклонение $\sigma$.
Дисперсия сгенерированных чисел равна $\sigma^2$.

[in]prndУказатель на структуру random_t параметров датчиков псевдослучайных чисел.
Структура должна быть предварительно заполнена функцией random_init.
Данный указатель может быть NULL, тогда будет использоваться встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд, например в криптографии, данный режим использовать не рекомендуется. Нет гарантии в качестве произведенной случайной последовательности если параметр prnd задан как NULL.

Возвращает
RES_OK — вектор нормально распределенных псевдослучайных чисел рассчитан успешно.
В противном случае код ошибки.

Пример использования функции:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 50000
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handles */
random_t rnd = {0}; /* random structure */
hdspl = dspl_load(); /* Load DSPL function */
double *x = NULL;
double *y = NULL;
int err;
x = (double*) malloc(N * sizeof(double));
y = (double*) malloc(N * sizeof(double));
if(!x || !y)
{
err = ERROR_PTR;
printf("malloc error!\n");
goto exit_label;
}
err = random_init(&rnd, RAND_TYPE_MRG32K3A, NULL);
if(err != RES_OK)
goto exit_label;
err = randn(x, N, 0.0, 1.0, &rnd);
if(err != RES_OK)
goto exit_label;
err = randn(y, N, 0.0, 1.0, &rnd);
if(err != RES_OK)
goto exit_label;
/* Save to files "dat/randu_mrg32k3a.txt" */
writetxt(x, y, N, "dat/randn_mrg32k3a.txt");
/***************************************************************************/
/* plotting by GNUPLOT */
/***************************************************************************/
/* Create window plot */
err = gnuplot_create(argc, argv, 420, 420, "img/randn_test.png", &hplot);
if(err != RES_OK)
goto exit_label;
gnuplot_cmd(hplot, "set xlabel 'x'");
gnuplot_cmd(hplot, "set ylabel 'y'");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set xrange[-3:3]");
gnuplot_cmd(hplot, "set yrange[-3:3]");
gnuplot_cmd(hplot, "set title 'MRG32K3A'");
gnuplot_cmd(hplot, "plot 'dat/randn_mrg32k3a.txt' with points pointtype 0");
exit_label:
if(x)
free(x);
if(y)
free(y);
if(hplot)
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Программа рассчитывает независимые векторы нормально распределенных псевдослучайных чисел, $\mu = 0$ и $\sigma=1$.

В результате выполнения программы можно увидеть график:

randn_test.png
Автор
Бахурин Сергей. www.dsplib.org

См. определение в файле randgen.c строка 217

◆ random_init()

int random_init ( random_t prnd,
int  type,
void *  seed 
)

Инициализация датчиков псевдослучайных чисел.


Аргументы
[in,out]prndУказатель на структуру параметров и векторов состояния датчиков псевдослучайных чисел, которая будет инициализирована.

[in]typeТип датчика псевдослучайных чисел:
RAND_TYPE_MRG32K3A - 32-битный датчик MRG32K3A
RAND_TYPE_MT19937  - 64-битный датчик MT19937-64
[in]seedУказатель на начальную инициализацию датчика.
Данный указатель имеет тип void*, поскольку параметр инициализации зависит от типа датчика. Например если инициализируем датчик MRG32K3A, т.е. параметр type задан как RAND_TYPE_MRG32K3A, то данный указатель приводится к типу double:
random_t rnd = {0};
double seed = 1234.0;
random_init(&rnd, RAND_TYPE_MRG32K3A, (void*)&seed);
Если же используется 64-битный датчик Вихрь Мерсенна (type задан как RAND_TYPE_MT19937), то seed приводится к типу unsigned long long:
random_t rnd = {0};
unsigned long long seed = 1234353456;
random_init(&rnd, RAND_TYPE_MT19937, (void*)&seed);
При фиксированном начальном значении датчика, псевдослучайные числа будут повторяться при каждом запуске программы.
Указатель seed может быть NULL. В этом случае начальная инициализация датчиков будет задаваться случайными значениями и генерируемые псевдослучайные числа будут различными при каждом запуске программы.
Автор
Бахурин Сергей. www.dsplib.org

См. определение в файле randgen.c строка 35

◆ randu()

int randu ( double *  x,
int  n,
random_t prnd 
)

Генерация вектора равномерно-распределенных в интервале от 0 до 1 псевдослучайных чисел.


Аргументы
[in,out]x

Указатель на вектор случайных чисел.
Размер вектора [n x 1].
Память должна быть выделена.

Аргументы
[in]nРазмер вектора случайных чисел.

[in]prndУказатель на структуру random_t параметров датчиков псевдослучайных чисел.
Структура должна быть предварительно заполнена функцией random_init.
Данный указатель может быть NULL, тогда будет использоваться встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд, например в криптографии, данный режим использовать не рекомендуется. Нет гарантии в качестве произведенной случайной последовательности если параметр prnd задан как NULL.

Возвращает
RES_OK — вектор равномерно-распределенных псевдослучайных чисел рассчитан успешно.
В противном случае код ошибки.

Пример использования функции с различными датчиками псевдослучайных чисел приведен в следующем листинге:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 10000
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handles */
random_t rnd = {0}; /* random structure */
hdspl = dspl_load(); /* Load DSPL function */
double *x = NULL;
double *y = NULL;
int err;
x = (double*) malloc(N * sizeof(double));
y = (double*) malloc(N * sizeof(double));
if(!x || !y)
{
err = ERROR_PTR;
printf("malloc error!\n");
goto exit_label;
}
/***************************************************************************/
/* MRG32K3A random numbers generator */
/***************************************************************************/
double seed_mrg32k3a = 1234.0;
err = random_init(&rnd, RAND_TYPE_MRG32K3A, (void*)(&seed_mrg32k3a));
if(err != RES_OK)
goto exit_label;
err = randu(x, N, &rnd);
if(err != RES_OK)
goto exit_label;
err = randu(y, N, &rnd);
if(err != RES_OK)
goto exit_label;
/* Save to files "dat/randu_mrg32k3a.txt" */
writetxt(x, y, N, "dat/randu_mrg32k3a.txt");
/***************************************************************************/
/* MT19937 random numbers generator */
/***************************************************************************/
unsigned long long seed_mt19937 = 1234353456;
err = random_init(&rnd, RAND_TYPE_MT19937, (void*)(&seed_mt19937));
if(err != RES_OK)
goto exit_label;
err = randu(x, N, &rnd);
if(err != RES_OK)
goto exit_label;
err = randu(y, N, &rnd);
if(err != RES_OK)
goto exit_label;
/* Save to files "dat/randu_mrg32k3a.txt" */
writetxt(x, y, N, "dat/randu_mt19937.txt");
/***************************************************************************/
/* Standard C random numbers generator */
/***************************************************************************/
err = randu(x, N, NULL);
if(err != RES_OK)
goto exit_label;
err = randu(y, N, NULL);
if(err != RES_OK)
goto exit_label;
/* Save to files "dat/randu_std.txt" */
writetxt(x, y, N, "dat/randu_std.txt");
/***************************************************************************/
/* plotting by GNUPLOT */
/***************************************************************************/
/* Create window plot */
err = gnuplot_create(argc, argv, 920, 320, "img/randu_test.png", &hplot);
if(err != RES_OK)
goto exit_label;
gnuplot_cmd(hplot, "set multiplot layout 1,3 rowsfirst");
gnuplot_cmd(hplot, "set xlabel 'x'");
gnuplot_cmd(hplot, "set ylabel 'y'");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set title 'MRG32K3A'");
gnuplot_cmd(hplot, "plot 'dat/randu_mrg32k3a.txt' with points pointtype 0");
gnuplot_cmd(hplot, "set title 'MT19937'");
gnuplot_cmd(hplot, "plot 'dat/randu_mt19937.txt' with points pointtype 0");
gnuplot_cmd(hplot, "set title 'Standard C'");
gnuplot_cmd(hplot, "plot 'dat/randu_std.txt' with points pointtype 0");
exit_label:
if(x)
free(x);
if(y)
free(y);
if(hplot)
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Программа рассчитывает независимые векторы равномерно-распределенных от 0 до 1 псевдослучайных чисел и выводит их на график для трех различных датчиков: MRG32K3A, MT19937-64 и встроенный датчик, определенный стандартом языка Си.

В результате выполнения программы можно увидеть график:

randu_test.png

Однако при детальном исследовании датчиков, можно обнаружить, что встроенный датчик, определенный стандартом языка Си, выдает значения на фиксированной сетке.

Чтобы проверить это можно выполнить следующую программу:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dspl.h"
#define N 10000
#define L 1.0E-3
int randu_accuracy(double* x, int n, double acc, random_t* prnd)
{
double z[512];
int cnt = 0;
int i;
int err = RES_OK;
if(!x)
return ERROR_PTR;
if(n < 1)
return ERROR_SIZE;
if(acc < 0.0)
while(cnt < n)
{
randu(z, 512, prnd);
for(i = 0; i < 512; i++)
{
if((z[i] < acc) && (cnt < n))
{
x[cnt] = z[i];
cnt++;
}
}
}
return RES_OK;
}
int main(int argc, char* argv[])
{
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handles */
random_t rnd = {0}; /* random structure */
hdspl = dspl_load(); /* Load DSPL function */
int err;
double *x = NULL;
double *y = NULL;
x = (double*) malloc(N * sizeof(double));
y = (double*) malloc(N * sizeof(double));
if(!x || !y)
{
err = ERROR_PTR;
printf("malloc error!\n");
goto exit_label;
}
/* MRG32K3A random numbers generator */
double seed_mrg32k3a = 1234.0;
random_init(&rnd, RAND_TYPE_MRG32K3A, (void*)(&seed_mrg32k3a));
randu_accuracy(x, N, L, &rnd); /* accumulate in x numbers from 0 to L */
randu_accuracy(y, N, L, &rnd); /* accumulate in y numbers from 0 to L */
writetxt(x, y, N, "dat/randu_acc_mrg32k3a.txt");
/* MT19937 random numbers generator */
unsigned long long seed_mt19937 = 1234353456;
random_init(&rnd, RAND_TYPE_MT19937, (void*)(&seed_mt19937));
randu_accuracy(x, N, L, &rnd); /* accumulate in x numbers from 0 to L */
randu_accuracy(y, N, L, &rnd); /* accumulate in y numbers from 0 to L */
writetxt(x, y, N, "dat/randu_acc_mt19937.txt");
/* Standard C random numbers generator */
randu_accuracy(x, N, L, NULL); /* accumulate in x numbers from 0 to L */
randu_accuracy(y, N, L, NULL); /* accumulate in y numbers from 0 to L */
writetxt(x, y, N, "dat/randu_acc_std.txt");
/* plotting by GNUPLOT */
/* Create window plot */
err = gnuplot_create(argc, argv, 920, 320, "img/randu_acc_test.png", &hplot);
if(err != RES_OK)
goto exit_label;
gnuplot_cmd(hplot, "set multiplot layout 1,3 rowsfirst");
gnuplot_cmd(hplot, "set xlabel 'x'");
gnuplot_cmd(hplot, "set ylabel 'y'");
gnuplot_cmd(hplot, "set xtics ('0' 0,'5E-4' 0.0005,' 1E-3' 0.001)");
gnuplot_cmd(hplot, "set ytics ('0' 0,'5E-4' 0.0005,' 1E-3' 0.001)");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set title 'MRG32K3A'");
gnuplot_cmd(hplot, "plot 'dat/randu_acc_mrg32k3a.txt' with points pointtype 0");
gnuplot_cmd(hplot, "set title 'MT19937'");
gnuplot_cmd(hplot, "plot 'dat/randu_acc_mt19937.txt' with points pointtype 0");
gnuplot_cmd(hplot, "set title 'Standard C'");
gnuplot_cmd(hplot, "plot 'dat/randu_acc_std.txt' with points pointtype 0");
exit_label:
if(x)
free(x);
if(y)
free(y);
if(hplot)
gnuplot_close(hplot);
/* free dspl handle */
dspl_free(hdspl);
return 0;
}

Данная программа аккумулирует только значения датчиков в интервале от 0 до 0.001 и выводит их на график:

randu_acc_test.png

Из графика хорошо видно, что данные встроенного датчика выдаются на равноотстоящей сетке значений, в отличии от датчиков MRG32K3A и MT19937-64, которые сохранили псевдослучайный характер.

Автор
Бахурин Сергей. www.dsplib.org

См. определение в файле randgen.c строка 262

Используется в randb(), randb2(), randi() и randn().