Console Library 4.7.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
matools.h
Go to the documentation of this file.
1
10
11/*
12Copyright (c) 2026 MrXie1109
13
14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal
16in the Software without restriction, including without limitation the rights
17to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18copies of the Software, and to permit persons to whom the Software is
19furnished to do so, subject to the following conditions:
20
21The above copyright notice and this permission notice shall be included in all
22copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30SOFTWARE.
31*/
32
33#pragma once
34#define _USE_MATH_DEFINES
35#include <iostream>
36#include <numeric>
37#include <cmath>
38#include "multiarray.h"
39#include "random.h"
40
41#ifndef M_PI
42#define M_PI 3.14159265358979323846
43#endif
44
45namespace console
46{
52
53 // ---------------------------- 统计 ----------------------------
61 template <class T, size_t... Dims>
62 double mean(const MultiArray<T, Dims...> &arr)
63 {
64 return double(sum(arr)) / arr.fsize();
65 }
66
75 template <class T, size_t... Dims>
76 double variance(const MultiArray<T, Dims...> &arr, bool sample = true)
77 {
78 double m = mean(arr);
79 double sq_sum = 0;
80 arr.for_each([&](const T &x)
81 {
82 double d = double(x) - m;
83 sq_sum += d * d; });
84 return sq_sum / (arr.fsize() - (sample ? 1 : 0));
85 }
86
95 template <class T, size_t... Dims>
96 double stddev(const MultiArray<T, Dims...> &arr, bool sample = true)
97 {
98 return std::sqrt(variance(arr, sample));
99 }
100
101 // ---------------------------- 向量运算(一维) ----------------------------
110 template <class T, size_t N>
112 {
113 return std::inner_product(a.fbegin(), a.fend(), b.fbegin(), T{});
114 }
115
123 template <class T, size_t N>
124 double norm(const MultiArray<T, N> &a)
125 {
126 return std::sqrt(double(dot(a, a)));
127 }
128
137 template <class T, size_t N>
138 double cosine(const MultiArray<T, N> &a, const MultiArray<T, N> &b)
139 {
140 return dot(a, b) / (norm(a) * norm(b));
141 }
142
150 template <class T, size_t N>
152 {
153 double len = norm(a);
154 if (len == 0)
155 return a;
156 MultiArray<T, N> result;
157 auto ai = a.fbegin();
158 auto ri = result.fbegin();
159 while (ri != result.fend())
160 *ri++ = *ai++ / len;
161 return result;
162 }
163
172 template <class T, size_t N>
173 double euclidean(const MultiArray<T, N> &a, const MultiArray<T, N> &b)
174 {
175 double sum = 0;
176 auto ai = a.fbegin();
177 auto bi = b.fbegin();
178 while (ai != a.fend())
179 {
180 double d = *ai++ - *bi++;
181 sum += d * d;
182 }
183 return std::sqrt(sum);
184 }
185
194 template <class T, size_t N>
195 double manhattan(const MultiArray<T, N> &a, const MultiArray<T, N> &b)
196 {
197 double sum = 0;
198 auto ai = a.fbegin();
199 auto bi = b.fbegin();
200 while (ai != a.fend())
201 sum += std::abs(*ai++ - *bi++);
202 return sum;
203 }
204
205 // ---------------------------- 矩阵运算(二维) ----------------------------
216 template <class T, size_t M, size_t N, size_t K>
218 const MultiArray<T, N, K> &B)
219 {
221 for (size_t i = 0; i < M; ++i)
222 for (size_t j = 0; j < N; ++j)
223 for (size_t k = 0; k < K; ++k)
224 C[i][k] += A[i][j] * B[j][k];
225 return C;
226 }
227
236 template <class T, size_t M, size_t N>
238 {
240 for (size_t i = 0; i < M; i++)
241 for (size_t j = 0; j < N; j++)
242 B[j][i] = A[i][j];
243 return B;
244 }
245
252 template <class T, size_t N>
254 {
256 for (size_t i = 0; i < N; i++)
257 I[i][i] = T{1};
258 return I;
259 }
260
268 template <class T, size_t N>
270 {
271 T result{};
272 for (size_t i = 0; i < N; i++)
273 result += A[i][i];
274 return result;
275 }
276
284 template <class T>
286 {
287 return MultiArray<T, 3>{
288 a[1] * b[2] - a[2] * b[1],
289 a[2] * b[0] - a[0] * b[2],
290 a[0] * b[1] - a[1] * b[0]};
291 }
292
293 // ---------------------------- 元素级运算 ----------------------------
303 template <class T, size_t... Dims>
305 T low, T high)
306 {
307 MultiArray<T, Dims...> result;
308 auto ri = result.fbegin();
309 auto ai = arr.fbegin();
310 while (ri != result.fend())
311 {
312 *ri = *ai < low ? low : (*ai > high ? high : *ai);
313 ++ri;
314 ++ai;
315 }
316 return result;
317 }
318
326 template <class T, size_t... Dims>
328 {
329 MultiArray<T, Dims...> result;
330 auto ri = result.fbegin();
331 auto ai = arr.fbegin();
332 while (ri != result.fend())
333 *ri++ = std::abs(*ai++);
334 return result;
335 }
336
337 // ---------------------------- 随机初始化 ----------------------------
346 template <class T, size_t... Dims>
347 void randomize(MultiArray<T, Dims...> &arr, T min = 0, T max = 100)
348 {
350 arr.for_each([&](T &x)
351 { x = dis(default_gen()); });
352 }
353
362 template <class T, size_t... Dims>
364 {
365 std::normal_distribution<T> dis(mean, stddev);
366 arr.for_each([&](T &x)
367 { x = dis(default_gen()); });
368 }
369
378 template <class T, size_t... Dims>
379 void linspace(MultiArray<T, Dims...> &arr, T start, T end)
380 {
381 size_t n = arr.fsize();
382 for (size_t i = 0; i < n; i++)
383 arr.fbegin()[i] = start + (end - start) * i / (n - 1);
384 }
385
386 // ---------------------------- 其他 ----------------------------
394 template <class T, size_t... Dims>
396 {
397 return std::accumulate(arr.fbegin(), arr.fend(), T{1}, std::multiplies<T>());
398 }
399
408 template <class T, size_t... Dims>
410 {
411 if (k >= arr.fsize())
412 k = arr.fsize() - 1;
413 std::nth_element(arr.fbegin(), arr.fbegin() + k, arr.fend());
414 return arr.fbegin()[k];
415 }
416
426 template <class T, size_t N, size_t K>
427 MultiArray<T, N + K - 1> convolve1d(const MultiArray<T, N> &signal,
428 const MultiArray<T, K> &kernel)
429 {
430 MultiArray<T, N + K - 1> result{};
431 for (size_t i = 0; i < N; i++)
432 for (size_t j = 0; j < K; j++)
433 result[i + j] += signal[i] * kernel[j];
434 return result;
435 }
436
437 // ---------------------------- 三角函数 ----------------------------
445 template <class T, size_t... Dims>
447 {
448 MultiArray<T, Dims...> result;
449 auto ri = result.fbegin();
450 auto ai = arr.fbegin();
451 while (ri != result.fend())
452 *ri++ = std::sin(*ai++);
453 return result;
454 }
455
463 template <class T, size_t... Dims>
465 {
466 MultiArray<T, Dims...> result;
467 auto ri = result.fbegin();
468 auto ai = arr.fbegin();
469 while (ri != result.fend())
470 *ri++ = std::cos(*ai++);
471 return result;
472 }
473
481 template <class T, size_t... Dims>
483 {
484 MultiArray<T, Dims...> result;
485 auto ri = result.fbegin();
486 auto ai = arr.fbegin();
487 while (ri != result.fend())
488 *ri++ = std::tan(*ai++);
489 return result;
490 }
491
499 template <class T, size_t... Dims>
501 {
502 MultiArray<T, Dims...> result;
503 auto ri = result.fbegin();
504 auto ai = arr.fbegin();
505 while (ri != result.fend())
506 *ri++ = std::asin(*ai++);
507 return result;
508 }
509
517 template <class T, size_t... Dims>
519 {
520 MultiArray<T, Dims...> result;
521 auto ri = result.fbegin();
522 auto ai = arr.fbegin();
523 while (ri != result.fend())
524 *ri++ = std::acos(*ai++);
525 return result;
526 }
527
535 template <class T, size_t... Dims>
537 {
538 MultiArray<T, Dims...> result;
539 auto ri = result.fbegin();
540 auto ai = arr.fbegin();
541 while (ri != result.fend())
542 *ri++ = std::atan(*ai++);
543 return result;
544 }
545
553 template <class T, size_t... Dims>
555 {
556 MultiArray<T, Dims...> result;
557 auto ri = result.fbegin();
558 auto ai = arr.fbegin();
559 while (ri != result.fend())
560 *ri++ = std::sinh(*ai++);
561 return result;
562 }
563
571 template <class T, size_t... Dims>
573 {
574 MultiArray<T, Dims...> result;
575 auto ri = result.fbegin();
576 auto ai = arr.fbegin();
577 while (ri != result.fend())
578 *ri++ = std::cosh(*ai++);
579 return result;
580 }
581
589 template <class T, size_t... Dims>
591 {
592 MultiArray<T, Dims...> result;
593 auto ri = result.fbegin();
594 auto ai = arr.fbegin();
595 while (ri != result.fend())
596 *ri++ = std::tanh(*ai++);
597 return result;
598 }
599
600 // ---------------------------- 指数对数 ----------------------------
608 template <class T, size_t... Dims>
610 {
611 MultiArray<T, Dims...> result;
612 auto ri = result.fbegin();
613 auto ai = arr.fbegin();
614 while (ri != result.fend())
615 *ri++ = std::exp(*ai++);
616 return result;
617 }
618
626 template <class T, size_t... Dims>
628 {
629 MultiArray<T, Dims...> result;
630 auto ri = result.fbegin();
631 auto ai = arr.fbegin();
632 while (ri != result.fend())
633 *ri++ = std::log(*ai++);
634 return result;
635 }
636
644 template <class T, size_t... Dims>
646 {
647 MultiArray<T, Dims...> result;
648 auto ri = result.fbegin();
649 auto ai = arr.fbegin();
650 while (ri != result.fend())
651 *ri++ = std::log10(*ai++);
652 return result;
653 }
654
663 template <class T, size_t... Dims>
664 MultiArray<T, Dims...> pow(const MultiArray<T, Dims...> &arr, T exponent)
665 {
666 MultiArray<T, Dims...> result;
667 auto ri = result.fbegin();
668 auto ai = arr.fbegin();
669 while (ri != result.fend())
670 *ri++ = std::pow(*ai++, exponent);
671 return result;
672 }
673
682 template <class T, size_t... Dims>
683 MultiArray<T, Dims...> pow(const MultiArray<T, Dims...> &base,
685 {
686 MultiArray<T, Dims...> result;
687 auto bi = base.fbegin();
688 auto ei = exp.fbegin();
689 auto ri = result.fbegin();
690 while (ri != result.fend())
691 *ri++ = std::pow(*bi++, *ei++);
692 return result;
693 }
694
695 // ---------------------------- 取整函数 ----------------------------
703 template <class T, size_t... Dims>
705 {
706 MultiArray<T, Dims...> result;
707 auto ri = result.fbegin();
708 auto ai = arr.fbegin();
709 while (ri != result.fend())
710 *ri++ = std::floor(*ai++);
711 return result;
712 }
713
721 template <class T, size_t... Dims>
723 {
724 MultiArray<T, Dims...> result;
725 auto ri = result.fbegin();
726 auto ai = arr.fbegin();
727 while (ri != result.fend())
728 *ri++ = std::ceil(*ai++);
729 return result;
730 }
731
739 template <class T, size_t... Dims>
741 {
742 MultiArray<T, Dims...> result;
743 auto ri = result.fbegin();
744 auto ai = arr.fbegin();
745 while (ri != result.fend())
746 *ri++ = std::round(*ai++);
747 return result;
748 }
749
758 template <class T, size_t... Dims>
760 std::ostream &os,
761 const MultiArray<T, Dims...> &arr,
762 const char *name = "")
763 {
764 if (name && *name)
765 os << "=== " << name << " ===" << '\n';
766 os << " sum : " << sum(arr) << '\n';
767 os << " mean : " << mean(arr) << '\n';
768 os << " min : " << min(arr) << '\n';
769 os << " max : " << max(arr) << '\n';
770 os << " stddev: " << stddev(arr) << std::endl;
771 }
772 // end of matools group
774}
编译期固定维度的多维数组。
Definition multiarray.h:57
void print_stats(std::ostream &os, const MultiArray< T, Dims... > &arr, const char *name="")
打印数组的基本统计信息(和、均值、最小值、最大值、标准差)。
Definition matools.h:759
MultiArray< T, Dims... > ceil(const MultiArray< T, Dims... > &arr)
对数组每个元素向上取整。
Definition matools.h:722
MultiArray< T, 3 > cross(const MultiArray< T, 3 > &a, const MultiArray< T, 3 > &b)
三维向量的叉积。
Definition matools.h:285
double manhattan(const MultiArray< T, N > &a, const MultiArray< T, N > &b)
计算两个向量的曼哈顿距离(L1 距离)。
Definition matools.h:195
void randomize(MultiArray< T, Dims... > &arr, T min=0, T max=100)
用均匀分布随机数填充数组。
Definition matools.h:347
MultiArray< T, Dims... > round(const MultiArray< T, Dims... > &arr)
对数组每个元素四舍五入。
Definition matools.h:740
T trace(const MultiArray< T, N, N > &A)
计算方阵的迹(对角线元素之和)。
Definition matools.h:269
MultiArray< T, N, N > identity()
生成 N×N 的单位矩阵。
Definition matools.h:253
MultiArray< T, Dims... > abs(const MultiArray< T, Dims... > &arr)
计算数组中每个元素的绝对值。
Definition matools.h:327
double norm(const MultiArray< T, N > &a)
计算向量的欧几里得范数(L2 范数)。
Definition matools.h:124
T kth_smallest(MultiArray< T, Dims... > arr, size_t k)
查找第 k 小的元素(会修改数组顺序)。
Definition matools.h:409
MultiArray< T, Dims... > cos(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::cos。
Definition matools.h:464
MultiArray< T, Dims... > atan(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::atan。
Definition matools.h:536
MultiArray< T, Dims... > asin(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::asin。
Definition matools.h:500
MultiArray< T, Dims... > clamp(const MultiArray< T, Dims... > &arr, T low, T high)
将数组每个元素限制在 [low, high] 范围内。
Definition matools.h:304
MultiArray< T, M, K > matmul(const MultiArray< T, M, N > &A, const MultiArray< T, N, K > &B)
矩阵乘法(二维)。
Definition matools.h:217
MultiArray< T, Dims... > pow(const MultiArray< T, Dims... > &arr, T exponent)
对数组每个元素取幂(常数指数)。
Definition matools.h:664
MultiArray< T, Dims... > log(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::log(自然对数)。
Definition matools.h:627
MultiArray< T, Dims... > tanh(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::tanh。
Definition matools.h:590
T product(const MultiArray< T, Dims... > &arr)
计算所有元素的乘积。
Definition matools.h:395
MultiArray< T, N+K - 1 > convolve1d(const MultiArray< T, N > &signal, const MultiArray< T, K > &kernel)
一维卷积。
Definition matools.h:427
MultiArray< T, Dims... > tan(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::tan。
Definition matools.h:482
double euclidean(const MultiArray< T, N > &a, const MultiArray< T, N > &b)
计算两个向量的欧几里得距离。
Definition matools.h:173
MultiArray< T, Dims... > cosh(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::cosh。
Definition matools.h:572
MultiArray< T, Dims... > sinh(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::sinh。
Definition matools.h:554
double mean(const MultiArray< T, Dims... > &arr)
计算 MultiArray 中所有元素的算术平均值。
Definition matools.h:62
MultiArray< T, N, M > transpose(const MultiArray< T, M, N > &A)
矩阵转置。
Definition matools.h:237
MultiArray< T, Dims... > sin(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::sin。
Definition matools.h:446
MultiArray< T, Dims... > floor(const MultiArray< T, Dims... > &arr)
对数组每个元素向下取整。
Definition matools.h:704
MultiArray< T, Dims... > log10(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::log10(常用对数)。
Definition matools.h:645
void linspace(MultiArray< T, Dims... > &arr, T start, T end)
用线性等间距值填充数组。
Definition matools.h:379
T dot(const MultiArray< T, N > &a, const MultiArray< T, N > &b)
计算两个一维向量的点积。
Definition matools.h:111
MultiArray< T, N > normalize(const MultiArray< T, N > &a)
将向量归一化为单位向量。
Definition matools.h:151
MultiArray< T, Dims... > acos(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::acos。
Definition matools.h:518
double variance(const MultiArray< T, Dims... > &arr, bool sample=true)
计算方差。
Definition matools.h:76
double stddev(const MultiArray< T, Dims... > &arr, bool sample=true)
计算标准差。
Definition matools.h:96
double cosine(const MultiArray< T, N > &a, const MultiArray< T, N > &b)
计算两个向量的余弦相似度。
Definition matools.h:138
MultiArray< T, Dims... > exp(const MultiArray< T, Dims... > &arr)
对数组每个元素应用 std::exp。
Definition matools.h:609
void randomize_normal(MultiArray< T, Dims... > &arr, T mean=0, T stddev=1)
用正态分布随机数填充数组。
Definition matools.h:363
T min(const MultiArray< T, Dims... > &a)
求最小值。
Definition multiarray.h:1551
T max(const MultiArray< T, Dims... > &a)
求最大值。
Definition multiarray.h:1561
T sum(const MultiArray< T, Dims... > &a)
求和所有元素。
Definition multiarray.h:1538
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::mt19937 & default_gen()
获取一个全局的、以当前时间戳为种子的 Mersenne Twister 随机数引擎。
Definition random.h:54
typename uniform_distribution_impl< T >::type uniform_distribution_t
取得对印类型所对应的均匀分布。
Definition sfinae.h:381
提供编译期维度固定的多维数组容器 MultiArray,支持任意维度和元素级算术/逻辑/位运算。
本库所有组件所在的顶层命名空间。
@ C
Definition kb.h:55
@ M
Definition kb.h:65
@ A
Definition kb.h:53
@ N
Definition kb.h:66
@ B
Definition kb.h:54
@ K
Definition kb.h:63
@ T
Definition kb.h:72
@ I
Definition kb.h:61
提供随机数生成、随机选择、随机打乱等实用工具。