Skip to content

Commit 9a7ce19

Browse files
committed
linalg : matrix_frob_normを追加 (#1233)
Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com>
1 parent e02d8af commit 9a7ce19

File tree

2 files changed

+129
-1
lines changed

2 files changed

+129
-1
lines changed

reference/linalg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ BLAS 1, 2, 3のアルゴリズムでテンプレートパラメータが特に
7272
| [`vector_two_norm`](linalg/vector_two_norm.md) | xNRM2: ベクトルのユークリッドノルム(Euclidean norm)を求める (function template) | C++26 |
7373
| [`vector_abs_sum`](linalg/vector_abs_sum.md) | xASUM: ベクトル要素の絶対値和を求める (function template) | C++26 |
7474
| [`vector_idx_abs_max`](linalg/vector_idx_abs_max.md) | xIAMAX: ベクトル要素のうち最大絶対値インデクスを返す (function template) | C++26 |
75-
| `matrix_frob_norm` | 行列のフロベニウスノルム(Frobenius norm)を求める (function template) | C++26 |
75+
| [`matrix_frob_norm`](linalg/matrix_frob_norm.md) | 行列のフロベニウスノルム(Frobenius norm)を求める (function template) | C++26 |
7676
| `matrix_one_norm` | 行列の1ノルム(One norm)を求める (function template) | C++26 |
7777
| `matrix_inf_norm` | 行列の無限大ノルム(Infinity norm)を求める (function template) | C++26 |
7878

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# matrix_frob_norm
2+
3+
* [mathjax enable]
4+
* linalg[meta header]
5+
* function template[meta id-type]
6+
* std::linalg[meta namespace]
7+
* cpp26[meta cpp]
8+
9+
```cpp
10+
namespace std::linalg {
11+
template<in-matrix InMat, class Scalar>
12+
Scalar matrix_frob_norm(InMat A, Scalar init); // (1)
13+
14+
template<class ExecutionPolicy,
15+
in-matrix InMat,
16+
class Scalar>
17+
Scalar matrix_frob_norm(
18+
ExecutionPolicy&& exec,
19+
InMat A,
20+
Scalar init); // (2)
21+
22+
template<in-matrix InMat>
23+
auto matrix_frob_norm(InMat A); // (3)
24+
25+
template<class ExecutionPolicy, in-matrix InMat>
26+
auto matrix_frob_norm(ExecutionPolicy&& exec, InMat A); // (4)
27+
}
28+
```
29+
30+
31+
## 概要
32+
行列のフロベニウスノルムを計算する。
33+
34+
- (1): 逐次実行する。
35+
- (2): 指定された実行ポリシーに応じて実行する。
36+
- (3): (1)で`init`に`InMat::value_type`のデフォルト値を与えて逐次実行する。
37+
- (4): (2)で`init`に`InMat::value_type`のデフォルト値を与えて、指定された実行ポリシーに応じて実行する。
38+
39+
40+
## 適格要件
41+
- (1), (2): `decltype(init + `[`abs-if-needed`](abs-if-needed.md)`(declval<typename InMat::value_type>()) * abs-if-needed(declval<typename InMat::value_type>()))`が`Scalar`に変換可能。
42+
43+
## 効果
44+
- (3), (4): `T`を`decltype(abs-if-needed(declval<typename InMat::value_type>()) * abs-if-needed(declval<typename InMat::value_type>()))`とすると、
45+
+ (3): `matrix_frob_norm(v, T{})`を返す。
46+
+ (4): `matrix_frob_norm(std::forward<ExecutionPolicy>(exec), v, T{})`を返す。
47+
48+
49+
## 戻り値
50+
- (1), (2): `A`が $m \times n$ 行列とすると、以下の式の値を返す。
51+
52+
$$
53+
\sqrt{\sum_{i = 0}^{m - 1} \sum_{j = 0}^{n - 1} |\verb|A[|i, j\verb|]||^2 + \verb|init|^2}
54+
$$
55+
56+
- (3), (4): `T`を`decltype(abs-if-needed(declval<typename InMat::value_type>()) * abs-if-needed(declval<typename InMat::value_type>()))`とすると、
57+
+ (3): `matrix_frob_norm(v, T{})`を返す。
58+
+ (4): `matrix_frob_norm(std::forward<ExecutionPolicy>(exec), v, T{})`を返す。
59+
60+
61+
## 備考
62+
- (1), (2): もし`InMat::value_type`と`Scalar`がどちらも浮動小数点数型または`std::complex`の特殊化で、`Scalar`が`InMat::value_type`より精度が高い場合、和の各項は`Scalar`またはより高い精度の型が使われる。
63+
64+
65+
## 例
66+
**[注意] 処理系にあるコンパイラで確認していないため、間違っているかもしれません。**
67+
68+
```cpp
69+
#include <array>
70+
#include <cmath>
71+
#include <execution>
72+
#include <iostream>
73+
#include <linalg>
74+
#include <mdspan>
75+
76+
int main()
77+
{
78+
constexpr size_t M = 4;
79+
constexpr size_t N = 4;
80+
81+
std::array<double, M * N> vec;
82+
83+
std::mdspan v(vec.data(), M, N);
84+
85+
for(int i = 0; i < A.extent(0); ++i) {
86+
for(int j = 0; j < A.extent(1); ++j) {
87+
A(i,j) = ((i + j) % 2 == 0 ? 1.0 : -1.0) / (i * A.extent(1) + j + 1);
88+
}
89+
}
90+
91+
std::cout << stdex::linalg::matrix_frob_norm(A, 1.0 / (M + N + 1)) << '\n'
92+
<< stdex::linalg::matrix_frob_norm(std::execution::par, A, 1.0 / (M + N + 1)) << '\n'
93+
<< stdex::linalg::matrix_frob_norm(A) << '\n'
94+
<< stdex::linalg::matrix_frob_norm(std::execution::par, A) << '\n';
95+
96+
return 0;
97+
}
98+
```
99+
100+
101+
### 出力
102+
```
103+
1.2636
104+
1.2636
105+
1.25871
106+
1.25871
107+
```
108+
109+
110+
## バージョン
111+
### 言語
112+
- C++26
113+
114+
### 処理系
115+
- [Clang](/implementation.md#clang): ??
116+
- [GCC](/implementation.md#gcc): ??
117+
- [ICC](/implementation.md#icc): ??
118+
- [Visual C++](/implementation.md#visual_cpp): ??
119+
120+
121+
## 関連項目
122+
- [`execution`](/reference/execution.md)
123+
- [`mdspan`](/reference/mdspan.md)
124+
125+
126+
## 参照
127+
- [P0788R3 Standard Library Specification in a Concepts and Contracts World](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0788r3.pdf)
128+

0 commit comments

Comments
 (0)