Skip to content

Commit 5726d37

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

File tree

2 files changed

+190
-1
lines changed

2 files changed

+190
-1
lines changed

reference/linalg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ BLAS 1, 2, 3のアルゴリズムでテンプレートパラメータが特に
9090
| [`matrix_rank_1_update_c`](linalg/matrix_rank_1_update_c.md) | xGERC: 複素行列のRank-1更新 (function template) | C++26 |
9191
| [`symmetric_matrix_rank_1_update`](linalg/symmetric_matrix_rank_1_update.md) | xSYR: 対称行列のRank-1更新 (function template) | C++26 |
9292
| [`hermitian_matrix_rank_1_update`](linalg/hermitian_matrix_rank_1_update.md) | xHER: ハミルトニアン行列のRank-1更新 (function template) | C++26 |
93-
| `symmetric_matrix_rank_2_update` | xSYR2: 対称行列のRank-2更新 (function template) | C++26 |
93+
| [`symmetric_matrix_rank_2_update`](linalg/symmetric_matrix_rank_2_update.md) | xSYR2: 対称行列のRank-2更新 (function template) | C++26 |
9494
| `hermitian_matrix_rank_2_update` | xHER2: ハミルトニアン行列のRank-2更新 (function template) | C++26 |
9595

9696

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# symmetric_matrix_rank_2_update
2+
3+
4+
* [mathjax enable]
5+
* linalg[meta header]
6+
* function template[meta id-type]
7+
* std::linalg[meta namespace]
8+
* cpp26[meta cpp]
9+
10+
11+
```cpp
12+
namespace std::linalg {
13+
template<in-vector InVec1,
14+
in-vector InVec2,
15+
possibly-packed-inout-matrix InOutMat,
16+
class Triangle>
17+
void symmetric_matrix_rank_2_update(
18+
InVec1 x,
19+
InVec2 y,
20+
InOutMat A,
21+
Triangle t); // (1)
22+
23+
template<class ExecutionPolicy,
24+
in-vector InVec1,
25+
in-vector InVec2,
26+
possibly-packed-inout-matrix InOutMat,
27+
class Triangle>
28+
void symmetric_matrix_rank_2_update(
29+
ExecutionPolicy&& exec,
30+
InVec1 x,
31+
InVec2 y,
32+
InOutMat A,
33+
Triangle t); // (2)
34+
}
35+
```
36+
37+
38+
## 概要
39+
対称かつ共役を取らないrank-2 updateを対称行列に行う。
40+
引数`t`は対称行列の成分が上三角にあるのか、それとも下三角にあるのかを示す。
41+
42+
- (1): $A \leftarrow A + xy^T + yx^T$
43+
- (2): (1)を指定された実行ポリシーで実行する。
44+
45+
46+
## 適格要件
47+
- `Triangle`は[`upper_triangle_t`](upper_triangle_t.md)または[`lower_triangle_t`](lower_triangle_t.md)
48+
- `InMat`が[`layout_blas_packed`](layout_blas_packed.md)を持つなら、レイアウトの`Triangle`テンプレート引数とこの関数の`Triangle`テンプレート引数が同じ型
49+
- [`possibly-multipliable`](possibly-multipliable.md)`<decltype(A), decltype(x), decltype(y)>()`が`true`
50+
51+
52+
## 事前条件
53+
- `A.extent(0) == A.extent(1)`
54+
- [`multipliable`](multipliable.md)`(A, x, y) == true`
55+
56+
57+
## 効果
58+
$A \leftarrow A + xx^T$
59+
60+
61+
## 戻り値
62+
なし
63+
64+
65+
## 計算量
66+
$O(\verb|x.extent(0)| \times \verb|y.extent(0)|)$
67+
68+
69+
## 例
70+
**[注意] 処理系にあるコンパイラで確認していないため、間違っているかもしれません。**
71+
72+
```cpp example
73+
#include <array>
74+
#include <iostream>
75+
#include <linalg>
76+
#include <mdspan>
77+
#include <vector>
78+
79+
template <class Matrix>
80+
void print_mat(const Matrix& A) {
81+
for(int i = 0; i < A.extent(0); ++i) {
82+
for(int j = 0; j < i; ++j) {
83+
std::cout << A[j, i] << ' ';
84+
}
85+
for(int j = i; j < A.extent(1) - 1; ++j) {
86+
std::cout << A[i, j] << ' ';
87+
}
88+
std::cout << A[i, A.extent(1) - 1] << '\n';
89+
}
90+
}
91+
92+
template <class Matrix>
93+
void init_mat(Matrix& A) {
94+
for(int i = 0; i < A.extent(0); ++i) {
95+
for(int j = i; j < A.extent(1); ++j) {
96+
A[i,j] = A.extent(1) * i + j;
97+
}
98+
}
99+
}
100+
101+
int main()
102+
{
103+
constexpr size_t N = 4;
104+
105+
std::vector<double> A_vec(N * N);
106+
std::vector<double> x_vec(N);
107+
std::array<double, N> y_vec;
108+
109+
std::mdspan<
110+
double,
111+
std::extents<size_t, N, N>,
112+
std::linalg::layout_blas_packed<
113+
std::linalg::upper_triangle_t,
114+
std::linalg::row_major_t>
115+
> A(A_vec.data());
116+
std::mdspan x(x_vec.data(), N);
117+
std::mdspan y(y_vec.data(), N);
118+
119+
init_mat(A);
120+
121+
for (int i = 0; i < x.extent(0); ++i) {
122+
x[i] = i;
123+
}
124+
for (int i = 0; i < y.extent(0); ++i) {
125+
y[i] = i + y.extent(0);
126+
}
127+
128+
// (1)
129+
std::cout << "(1)\n";
130+
std::linalg::symmetric_matrix_rank_1_update(
131+
x,
132+
y,
133+
A,
134+
std::linalg::upper_triangle);
135+
print_mat(A);
136+
137+
// (2)
138+
init_mat(A);
139+
std::cout << "(2)\n";
140+
std::linalg::symmetric_matrix_rank_1_update(
141+
std::execution::par,
142+
x,
143+
y,
144+
A,
145+
std::linalg::upper_triangle);
146+
print_mat(A);
147+
148+
return 0;
149+
}
150+
```
151+
152+
153+
### 出力
154+
```
155+
(1)
156+
0 5 10 15
157+
5 15 22 29
158+
10 22 34 43
159+
15 29 43 57
160+
(2)
161+
0 5 10 15
162+
5 15 22 29
163+
10 22 34 43
164+
15 29 43 57
165+
```
166+
167+
168+
## バージョン
169+
### 言語
170+
- C++26
171+
172+
### 処理系
173+
- [Clang](/implementation.md#clang): ??
174+
- [GCC](/implementation.md#gcc): ??
175+
- [ICC](/implementation.md#icc): ??
176+
- [Visual C++](/implementation.md#visual_cpp): ??
177+
178+
179+
## 関連項目
180+
- [`execution`](/reference/execution.md)
181+
- [`mdspan`](/reference/mdspan.md)
182+
- [`upper_triangle_t`](upper_triangle_t.md)
183+
- [`lower_triangle_t`](lower_triangle_t.md)
184+
185+
186+
## 参照
187+
- [P1673R13 A free function linear algebra interface based on the BLAS](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1673r13.html)
188+
- [LAPACK: {he,sy}r: Hermitian/symmetric rank-2 update](https://netlib.org/lapack/explore-html/dd/de5/group__her2.html)
189+

0 commit comments

Comments
 (0)