kopia lustrzana https://github.com/Dsplib/libdspl-2.0
386 wiersze
18 KiB
Plaintext
386 wiersze
18 KiB
Plaintext
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\struct random_t
|
||
\brief Структура параметров датчиков псевдослучайных чисел.
|
||
|
||
Структура хранит инициализацию и текущие регистры различных датчиков
|
||
псевдослучайных чисел. В библиотеке используются следующие датчики:
|
||
\li MRG32K3A -- 32 битный датчик разработан Пьером Лекуэром [1].
|
||
\li MT19937-64 -- 64-битный датчик
|
||
<a href = "https://en.wikipedia.org/wiki/Mersenne_Twister">
|
||
Вихрь Мерсенна
|
||
</a> [2, 3].
|
||
|
||
\note
|
||
[1] Pierre L'Ecuyer, (1999) Good Parameters and Implementations for Combined
|
||
Multiple Recursive Random Number Generators. Operations Research
|
||
47(1):159-164. https://doi.org/10.1287/opre.47.1.159 \n\n
|
||
[2] T. Nishimura, ``Tables of 64-bit Mersenne Twisters // ACM Transactions
|
||
on Modeling and Computer Simulation 10. (2000) 348--357. \n\n
|
||
[3] M. Matsumoto and T. Nishimura Mersenne Twister: a 623-dimensionally
|
||
equidistributed uniform pseudorandom number generator // ACM Transactions
|
||
on Modeling and Computer Simulation 8. (Jan. 1998) 3--30. \n\n
|
||
|
||
\param mrg32k3a_seed
|
||
Начальная инициализация датчика MRG32K3A. \n \n
|
||
|
||
|
||
\param mrg32k3a_x
|
||
Первый вектор состояния рекурсивного датчика MRG32K3A. \n \n
|
||
|
||
\param mrg32k3a_y
|
||
Второй вектор состояния рекурсивного датчика MRG32K3A. \n \n
|
||
|
||
\param mt19937_mt
|
||
Первый вектор состояния рекурсивного датчика MT19937-64. \n \n
|
||
|
||
\param mt19937_mti
|
||
Текущий индекс в векторе состояния датчика MT19937-64. \n \n
|
||
|
||
Параметры данной структуры заполняются автоматически функцией `random_init`
|
||
и используются функциями генерации псевдослучайных векторов.
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
***************************************************************************** */
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\fn int random_init(random_t* prnd, int type, void* seed)
|
||
\brief
|
||
Инициализация датчиков псевдослучайных чисел.
|
||
|
||
\param[in,out] prnd
|
||
Указатель на структуру параметров и векторов состояния
|
||
датчиков псевдослучайных чисел, которая будет инициализирована. \n\n
|
||
|
||
\param[in] type
|
||
Тип датчика псевдослучайных чисел:
|
||
\verbatim
|
||
RAND_TYPE_MRG32K3A - 32-битный датчик MRG32K3A
|
||
RAND_TYPE_MT19937 - 64-битный датчик MT19937-64
|
||
\endverbatim
|
||
|
||
\param[in] seed
|
||
Указатель на начальную инициализацию датчика. \n
|
||
Данный указатель имеет тип `void*`, поскольку параметр инициализации
|
||
зависит от типа датчика. Например если инициализируем датчик MRG32K3A,
|
||
т.е. параметр `type` задан как `RAND_TYPE_MRG32K3A`, то данный указатель
|
||
приводится к типу `double`:
|
||
\code
|
||
random_t rnd = {0};
|
||
double seed = 1234.0;
|
||
random_init(&rnd, RAND_TYPE_MRG32K3A, (void*)&seed);
|
||
\endcode
|
||
Если же используется 64-битный датчик Вихрь Мерсенна
|
||
(`type` задан как `RAND_TYPE_MT19937`), то `seed` приводится к типу
|
||
`unsigned long long`:
|
||
\code
|
||
random_t rnd = {0};
|
||
unsigned long long seed = 1234353456;
|
||
random_init(&rnd, RAND_TYPE_MT19937, (void*)&seed);
|
||
\endcode
|
||
При фиксированном начальном значении датчика, псевдослучайные числа будут
|
||
повторяться при каждом запуске программы. \n
|
||
Указатель `seed` может быть `NULL`. В этом случае начальная инициализация
|
||
датчиков будет задаваться случайными значениями и генерируемые псевдослучайные
|
||
числа будут различными при каждом запуске программы.
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
**************************************************************************** */
|
||
|
||
|
||
|
||
|
||
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\fn int randb(double* x, int n, random_t* prnd)
|
||
\brief
|
||
Генерация бинарного униполярного [0, 1] псевдослучайного вектора
|
||
|
||
Функция генерирует униполярный псевдослучайный вектор,
|
||
каждый элемент которого принимает равновероятное значение 0 или 1.
|
||
|
||
\param[in,out] x
|
||
Указатель на вектор случайных бинарных чисел. \n
|
||
Размер вектора `[n x 1]`. \n
|
||
Память должна быть выделена. \n\n
|
||
|
||
\param[in] n
|
||
Размер вектора `x`. \n\n
|
||
|
||
\param[in] prnd
|
||
Указатель на структуру `random_t` параметров датчиков
|
||
псевдослучайных чисел. \n
|
||
Структура должна быть предварительно заполнена функцией \ref random_init. \n
|
||
Данный указатель может быть `NULL`, тогда будет использоваться
|
||
встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд,
|
||
например в криптографии, данный режим использовать не рекомендуется.
|
||
Нет гарантии в качестве произведенной случайной последовательности если
|
||
параметр `prnd` задан как `NULL`. \n\n
|
||
|
||
\return
|
||
`RES_OK` --- вектор целых псевдослучайных чисел рассчитан успешно. \n
|
||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||
|
||
Пример использования функции:
|
||
|
||
\include randb_test.c
|
||
|
||
Программа рассчитывает униполярный [0, 1] и биполярный [-1, 1] бинарные
|
||
псевдослучайные векторы.
|
||
|
||
В результате выполнения программы можно увидеть график:
|
||
\image html randb_test.png
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
***************************************************************************** */
|
||
|
||
|
||
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\fn int randb2(double* x, int n, random_t* prnd)
|
||
\brief
|
||
Генерация бинарного биполярного [-1, 1] псевдослучайного вектора
|
||
|
||
Функция генерирует биполярный псевдослучайный вектор,
|
||
каждый элемент которого принимает равновероятное значение -1 или 1.
|
||
|
||
\param[in,out] x
|
||
Указатель на вектор случайных бинарных чисел. \n
|
||
Размер вектора `[n x 1]`. \n
|
||
Память должна быть выделена. \n\n
|
||
|
||
\param[in] n
|
||
Размер вектора `x`. \n\n
|
||
|
||
\param[in] prnd
|
||
Указатель на структуру `random_t` параметров датчиков
|
||
псевдослучайных чисел. \n
|
||
Структура должна быть предварительно заполнена функцией \ref random_init. \n
|
||
Данный указатель может быть `NULL`, тогда будет использоваться
|
||
встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд,
|
||
например в криптографии, данный режим использовать не рекомендуется.
|
||
Нет гарантии в качестве произведенной случайной последовательности если
|
||
параметр `prnd` задан как `NULL`. \n\n
|
||
|
||
\return
|
||
`RES_OK` --- вектор целых псевдослучайных чисел рассчитан успешно. \n
|
||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||
|
||
Пример использования функции:
|
||
|
||
\include randb_test.c
|
||
|
||
Программа рассчитывает униполярный [0, 1] и биполярный [-1, 1] бинарные
|
||
псевдослучайные векторы.
|
||
|
||
В результате выполнения программы можно увидеть график:
|
||
\image html randb_test.png
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
***************************************************************************** */
|
||
|
||
|
||
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\fn int randi(int* x, int n, int start, int stop, random_t* prnd)
|
||
\brief
|
||
Генерация целочисленного вектора равномерно
|
||
распределенных псевдослучайных чисел.
|
||
|
||
Функция генерирует псевдослучайный вектор целых чисел в диапазоне от `start`
|
||
до `stop` включительно.
|
||
|
||
\param[in,out] x
|
||
Указатель на вектор случайных чисел. \n
|
||
Размер вектора `[n x 1]`. \n
|
||
Память должна быть выделена. \n\n
|
||
|
||
\param[in] n
|
||
Размер вектора `x`. \n\n
|
||
|
||
\param[in] start
|
||
Начало диапазона целых чисел. \n\n
|
||
|
||
\param[in] stop
|
||
Конец диапазона целых чисел. \n\n
|
||
|
||
\param[in] prnd
|
||
Указатель на структуру `random_t` параметров датчиков
|
||
псевдослучайных чисел. \n
|
||
Структура должна быть предварительно заполнена функцией \ref random_init. \n
|
||
Данный указатель может быть `NULL`, тогда будет использоваться
|
||
встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд,
|
||
например в криптографии, данный режим использовать не рекомендуется.
|
||
Нет гарантии в качестве произведенной случайной последовательности если
|
||
параметр `prnd` задан как `NULL`. \n\n
|
||
|
||
\return
|
||
`RES_OK` --- вектор целых псевдослучайных чисел рассчитан успешно. \n
|
||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||
|
||
Пример использования функции:
|
||
|
||
\include randi_test.c
|
||
|
||
Программа рассчитывает целочисленный вектор
|
||
псевдослучайных чисел в диапазоне [-4, 3].
|
||
|
||
В результате выполнения программы можно увидеть график:
|
||
\image html randi_test.png
|
||
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
***************************************************************************** */
|
||
|
||
|
||
|
||
|
||
|
||
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\fn int randn(double* x, int n, double mu, double sigma, random_t* prnd)
|
||
\brief
|
||
Генерация вектора нормально распределенных псевдослучайных чисел.
|
||
|
||
Функция использует преобразование Бокса-Мюллера для приведения
|
||
равномерно-распределенных псевдослучайных чисел к нормальному распределению
|
||
с математическим ожиданием \f$\mu\f$ и средневадратическим
|
||
отклонением \f$\sigma\f$.
|
||
|
||
\param[in,out] x
|
||
Указатель на вектор случайных чисел. \n
|
||
Размер вектора `[n x 1]`. \n
|
||
Память должна быть выделена. \n\n
|
||
|
||
\param[in] n
|
||
Размер вектора случайных чисел. \n\n
|
||
|
||
\param[in] mu
|
||
Математическое ожидание \f$\mu\f$. \n\n
|
||
|
||
|
||
\param[in] sigma
|
||
Cредневадратическое отклонение \f$\sigma\f$. \n
|
||
Дисперсия сгенерированных чисел равна \f$\sigma^2\f$. \n\n
|
||
|
||
\param[in] prnd
|
||
Указатель на структуру `random_t` параметров датчиков
|
||
псевдослучайных чисел. \n
|
||
Структура должна быть предварительно заполнена функцией \ref random_init. \n
|
||
Данный указатель может быть `NULL`, тогда будет использоваться
|
||
встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд,
|
||
например в криптографии, данный режим использовать не рекомендуется.
|
||
Нет гарантии в качестве произведенной случайной последовательности если
|
||
параметр `prnd` задан как `NULL`. \n\n
|
||
|
||
\return
|
||
`RES_OK` --- вектор нормально распределенных
|
||
псевдослучайных чисел рассчитан успешно. \n
|
||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||
|
||
Пример использования функции:
|
||
|
||
\include randn_test.c
|
||
|
||
Программа рассчитывает независимые векторы нормально распределенных
|
||
псевдослучайных чисел, \f$\mu = 0\f$ и \f$\sigma=1\f$.
|
||
|
||
В результате выполнения программы можно увидеть график:
|
||
\image html randn_test.png
|
||
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
***************************************************************************** */
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*! ****************************************************************************
|
||
\ingroup SPEC_MATH_RAND_GEN_GROUP
|
||
\fn int randu(double* x, int n, random_t* prnd)
|
||
\brief
|
||
Генерация вектора равномерно-распределенных в интервале
|
||
от 0 до 1 псевдослучайных чисел.
|
||
|
||
\param[in,out] x
|
||
Указатель на вектор случайных чисел. \n
|
||
Размер вектора `[n x 1]`. \n
|
||
Память должна быть выделена. \n\n
|
||
|
||
\param[in] n
|
||
Размер вектора случайных чисел. \n\n
|
||
|
||
\param[in] prnd
|
||
Указатель на структуру `random_t` параметров датчиков
|
||
псевдослучайных чисел. \n
|
||
Структура должна быть предварительно заполнена функцией \ref random_init. \n
|
||
Данный указатель может быть `NULL`, тогда будет использоваться
|
||
встроенный датчик, определенный стандартом языка Си. Однако для серьезных нужд,
|
||
например в криптографии, данный режим использовать не рекомендуется.
|
||
Нет гарантии в качестве произведенной случайной последовательности если
|
||
параметр `prnd` задан как `NULL`. \n\n
|
||
|
||
\return
|
||
`RES_OK` --- вектор равномерно-распределенных
|
||
псевдослучайных чисел рассчитан успешно. \n
|
||
В противном случае \ref ERROR_CODE_GROUP "код ошибки".
|
||
|
||
Пример использования функции с различными датчиками псевдослучайных чисел
|
||
приведен в следующем листинге:
|
||
|
||
\include randu_test.c
|
||
|
||
Программа рассчитывает независимые векторы равномерно-распределенных
|
||
от 0 до 1 псевдослучайных чисел и выводит их на график для трех различных
|
||
датчиков: MRG32K3A, MT19937-64 и встроенный датчик, определенный
|
||
стандартом языка Си.
|
||
|
||
В результате выполнения программы можно увидеть график:
|
||
|
||
\image html randu_test.png
|
||
|
||
Однако при детальном исследовании датчиков, можно обнаружить, что встроенный
|
||
датчик, определенный стандартом языка Си,
|
||
выдает значения на фиксированной сетке.
|
||
|
||
Чтобы проверить это можно выполнить следующую программу:
|
||
|
||
\include randu_accuracy_test.c
|
||
|
||
Данная программа аккумулирует только значения датчиков в интервале
|
||
от 0 до 0.001 и выводит их на график:
|
||
|
||
\image html randu_acc_test.png
|
||
|
||
Из графика хорошо видно, что данные встроенного датчика выдаются на
|
||
равноотстоящей сетке значений, в отличии от датчиков MRG32K3A и MT19937-64,
|
||
которые сохранили псевдослучайный характер.
|
||
|
||
|
||
\author
|
||
Бахурин Сергей.
|
||
www.dsplib.org
|
||
***************************************************************************** */
|
||
|
||
|