Console Library 4.7.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
random.h
Go to the documentation of this file.
1
8
9/*
10Copyright (c) 2026 MrXie1109
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29*/
30
31#pragma once
32#include <random>
33#include <chrono>
34#include <cstdint>
35#include <utility>
36#include <initializer_list>
37#include <numeric>
38#include "sfinae.h" //for uniform_distribution_t
39#include "csexc.h"
40
41namespace console
42{
48
54 inline std::mt19937 &default_gen()
55 {
56 thread_local std::mt19937 gen(std::chrono::high_resolution_clock::now()
57 .time_since_epoch()
58 .count());
59 return gen;
60 }
61
66 inline void seed(unsigned int seed)
67 {
68 default_gen().seed(seed);
69 }
70
79 template <class T = int>
80 T randint(T min = 0, T max = 32767,
81 std::mt19937 &gen = default_gen())
82 {
83 return std::uniform_int_distribution<T>(min, max)(gen);
84 }
85
94 template <class T = double>
95 T uniform(T min = 0.0, T max = 1.0,
96 std::mt19937 &gen = default_gen())
97 {
98 return std::uniform_real_distribution<T>(min, max)(gen);
99 }
100
109 template <class C>
110 auto choice(C &c, std::mt19937 &gen = default_gen())
111 -> decltype(*std::begin(c))
112 {
113 if (std::begin(c) == std::end(c))
114 throw container_error("Empty container");
115 return *std::next(std::begin(c),
116 randint<size_t>(0, c.size() - 1, gen));
117 }
118
127 template <class C>
128 auto choice(C &&c, std::mt19937 &gen = default_gen())
129 -> std::remove_reference<decltype(*std::begin(c))>::type
130 {
131 if (std::begin(c) == std::end(c))
132 throw container_error("Empty container");
133 return *std::next(std::begin(c),
134 randint<size_t>(0, c.size() - 1, gen));
135 }
136
145 template <class T>
146 auto choice(std::initializer_list<T> init,
147 std::mt19937 &gen = default_gen())
148 -> decltype(*std::begin(init))
149 {
150 return choice<std::initializer_list<T>>((init), gen);
151 }
152
159 template <class C>
160 void shuffle(C &&c, std::mt19937 &gen = default_gen())
161 {
162 if (std::begin(c) == std::end(c))
163 return;
164 for (size_t i = c.size() - 1; i > 0; i--)
165 {
166 auto j = randint<size_t>(0, i, gen);
167 std::swap(*std::next(std::begin(c), i),
168 *std::next(std::begin(c), j));
169 }
170 }
171
181 template <class T = double>
182 std::vector<T> rnorm(size_t n, T mean = 0.0, T sd = 1.0,
183 std::mt19937 &gen = default_gen())
184 {
185 std::vector<T> vec(n);
186 std::normal_distribution<T> dist(mean, sd);
187 for (T &t : vec)
188 t = dist(gen);
189 return vec;
190 }
191
201 template <class T = double>
202 std::vector<T> runif(size_t n, T min = 0.0, T max = 1.0,
203 std::mt19937 &gen = default_gen())
204 {
205 std::vector<T> vec(n);
207 for (T &t : vec)
208 t = dist(gen);
209 return vec;
210 }
211
221 template <class T = int>
222 std::vector<T> rbinom(size_t n, T size, double prob,
223 std::mt19937 &gen = default_gen())
224 {
225 std::vector<T> vec(n);
226 std::binomial_distribution<T> dist(size, prob);
227 for (T &t : vec)
228 t = dist(gen);
229 return vec;
230 }
231
240 template <class T = int>
241 std::vector<T> rpois(size_t n, double lambda,
242 std::mt19937 &gen = default_gen())
243 {
244 std::vector<T> vec(n);
245 std::poisson_distribution<T> dist(lambda);
246 for (T &t : vec)
247 t = dist(gen);
248 return vec;
249 }
250
259 template <class T = double>
260 std::vector<T> rexp(size_t n, T rate = 1.0,
261 std::mt19937 &gen = default_gen())
262 {
263 std::vector<T> vec(n);
264 std::exponential_distribution<T> dist(rate);
265 for (T &t : vec)
266 t = dist(gen);
267 return vec;
268 }
269
280 template <class T = double>
281 std::vector<T> rgamma(size_t n, T shape, T rate = 1.0,
282 std::mt19937 &gen = default_gen())
283 {
284 std::vector<T> vec(n);
285 std::gamma_distribution<T> dist(shape, 1.0 / rate);
286 for (T &t : vec)
287 t = dist(gen);
288 return vec;
289 }
290
300 template <class T = double>
301 std::vector<T> rbeta(size_t n, T shape1, T shape2,
302 std::mt19937 &gen = default_gen())
303 {
304 std::vector<T> vec(n);
305 std::beta_distribution<T> dist(shape1, shape2);
306 for (T &t : vec)
307 t = dist(gen);
308 return vec;
309 }
310
320 template <class T = double>
321 std::vector<T> rchisq(size_t n, T df,
322 std::mt19937 &gen = default_gen())
323 {
324 return rgamma(n, df / 2.0, 0.5, gen);
325 }
326
335 template <class T = double>
336 std::vector<T> rt(size_t n, T df,
337 std::mt19937 &gen = default_gen())
338 {
339 std::vector<T> vec(n);
340 std::student_t_distribution<T> dist(df);
341 for (T &t : vec)
342 t = dist(gen);
343 return vec;
344 }
345
355 template <class T = double>
356 std::vector<T> rf(size_t n, T df1, T df2,
357 std::mt19937 &gen = default_gen())
358 {
359 std::vector<T> vec(n);
360 std::fisher_f_distribution<T> dist(df1, df2);
361 for (T &t : vec)
362 t = dist(gen);
363 return vec;
364 }
365
375 template <class T = double>
376 std::vector<T> rlnorm(size_t n, T meanlog = 0.0, T sdlog = 1.0,
377 std::mt19937 &gen = default_gen())
378 {
379 std::vector<T> vec(n);
380 std::lognormal_distribution<T> dist(meanlog, sdlog);
381 for (T &t : vec)
382 t = dist(gen);
383 return vec;
384 }
385
395 template <class T = double>
396 std::vector<T> rweibull(size_t n, T shape, T scale = 1.0,
397 std::mt19937 &gen = default_gen())
398 {
399 std::vector<T> vec(n);
400 std::weibull_distribution<T> dist(shape, scale);
401 for (T &t : vec)
402 t = dist(gen);
403 return vec;
404 }
405
417 template <class C>
418 auto sample(C &&c, size_t size, bool replace = false,
419 std::mt19937 &gen = default_gen())
420 -> std::vector<typename std::iterator_traits<decltype(std::begin(c))>::value_type>
421 {
422 using value_type = typename std::iterator_traits<decltype(std::begin(c))>::value_type;
423 std::vector<value_type> result;
424 result.reserve(size);
425 auto it_begin = std::begin(c);
426 auto it_end = std::end(c);
427 size_t n = std::distance(it_begin, it_end);
428 if (n == 0)
429 throw container_error(
430 "Cannot sample from empty container");
431 if (!replace && size > n)
432 throw container_error(
433 "Sample size exceeds container size when replace=false");
434 if (replace)
435 for (size_t i = 0; i < size; ++i)
436 {
437 result.push_back(*std::next(
438 it_begin,
439 std::uniform_int_distribution<size_t>(0, n - 1)(gen)));
440 }
441 else
442 {
443 std::vector<size_t> indices(n);
444 std::iota(indices.begin(), indices.end(), 0);
445 shuffle(indices, gen);
446 for (size_t i = 0; i < size; ++i)
447 result.push_back(*std::next(it_begin, indices[i]));
448 }
449
450 return result;
451 }
452
462 template <class T>
463 std::vector<T> sample(std::initializer_list<T> init,
464 size_t size,
465 bool replace = false,
466 std::mt19937 &gen = default_gen())
467 {
468 return sample<std::initializer_list<T>>(init, size, replace, gen);
469 }
470 // end of random group
472}
表示通用容器操作错误。
Definition csexc.h:135
定义 console 库使用的自定义异常类层次结构。
double mean(const MultiArray< T, Dims... > &arr)
计算 MultiArray 中所有元素的算术平均值。
Definition matools.h:62
T min(const MultiArray< T, Dims... > &a)
求最小值。
Definition multiarray.h:1551
T max(const MultiArray< T, Dims... > &a)
求最大值。
Definition multiarray.h:1561
auto sample(C &&c, size_t size, bool replace=false, std::mt19937 &gen=default_gen()) -> std::vector< typename std::iterator_traits< decltype(std::begin(c))>::value_type >
从容器中随机抽取指定数量的元素(有放回或无放回)。
Definition random.h:418
std::vector< T > rpois(size_t n, double lambda, std::mt19937 &gen=default_gen())
生成 n 个服从泊松分布(Poisson Distribution)的随机数。
Definition random.h:241
std::vector< T > rbeta(size_t n, T shape1, T shape2, std::mt19937 &gen=default_gen())
生成 n 个服从贝塔分布(Beta Distribution)的随机数。
Definition random.h:301
std::vector< T > rlnorm(size_t n, T meanlog=0.0, T sdlog=1.0, std::mt19937 &gen=default_gen())
生成 n 个服从对数正态分布(Lognormal Distribution)的随机数。
Definition random.h:376
std::vector< T > rbinom(size_t n, T size, double prob, std::mt19937 &gen=default_gen())
生成 n 个服从二项分布(Binomial Distribution)的随机数。
Definition random.h:222
T uniform(T min=0.0, T max=1.0, std::mt19937 &gen=default_gen())
生成一个指定范围内的随机浮点数(均匀分布)。
Definition random.h:95
auto choice(C &c, std::mt19937 &gen=default_gen()) -> decltype(*std::begin(c))
从容器中随机选择一个元素(左值版本,返回引用)。
Definition random.h:110
std::vector< T > rf(size_t n, T df1, T df2, std::mt19937 &gen=default_gen())
生成 n 个服从 F 分布(Fisher–Snedecor F-distribution)的随机数。
Definition random.h:356
void seed(unsigned int seed)
修改 default_gen 提供的随机数引擎的种子。
Definition random.h:66
std::vector< T > rexp(size_t n, T rate=1.0, std::mt19937 &gen=default_gen())
生成 n 个服从指数分布(Exponential Distribution)的随机数。
Definition random.h:260
std::vector< T > runif(size_t n, T min=0.0, T max=1.0, std::mt19937 &gen=default_gen())
生成 n 个服从均匀分布(Uniform Distribution)的随机数。
Definition random.h:202
void shuffle(C &&c, std::mt19937 &gen=default_gen())
随机打乱容器中元素的顺序(Fisher-Yates 洗牌算法)。
Definition random.h:160
std::mt19937 & default_gen()
获取一个全局的、以当前时间戳为种子的 Mersenne Twister 随机数引擎。
Definition random.h:54
T randint(T min=0, T max=32767, std::mt19937 &gen=default_gen())
生成一个指定范围内的随机整数(均匀分布)。
Definition random.h:80
std::vector< T > rt(size_t n, T df, std::mt19937 &gen=default_gen())
生成 n 个服从 t 分布(Student's t-distribution)的随机数。
Definition random.h:336
std::vector< T > rchisq(size_t n, T df, std::mt19937 &gen=default_gen())
生成 n 个服从卡方分布(Chi-squared Distribution)的随机数。
Definition random.h:321
std::vector< T > rnorm(size_t n, T mean=0.0, T sd=1.0, std::mt19937 &gen=default_gen())
生成 n 个服从正态分布(Normal Distribution)的随机数。
Definition random.h:182
std::vector< T > rweibull(size_t n, T shape, T scale=1.0, std::mt19937 &gen=default_gen())
生成 n 个服从韦布尔分布(Weibull Distribution)的随机数。
Definition random.h:396
std::vector< T > rgamma(size_t n, T shape, T rate=1.0, std::mt19937 &gen=default_gen())
生成 n 个服从伽马分布(Gamma Distribution)的随机数。
Definition random.h:281
typename uniform_distribution_impl< T >::type uniform_distribution_t
取得对印类型所对应的均匀分布。
Definition sfinae.h:381
本库所有组件所在的顶层命名空间。
@ C
Definition kb.h:55
@ T
Definition kb.h:72
提供编译期类型特征检测(SFINAE 工具),用于判断容器、可调用对象、迭代器、下标访问、字符串、可打印类型、字符类型等。