Skip to content

Commit 902bbca

Browse files
committed
linalg : symmetric_matrix_vector_productを追加 (#1233)
Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com>
1 parent 7f99ece commit 902bbca

File tree

2 files changed

+224
-1
lines changed

2 files changed

+224
-1
lines changed

reference/linalg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ BLAS 1, 2, 3のアルゴリズムでテンプレートパラメータが特に
8282
| 名前 | 説明 | 対応バージョン |
8383
|------|------|----------------|
8484
| [`matrix_vector_product`](linalg/matrix_vector_product.md) | xGEMV: 一般行列とベクトルの積を求める (function template) | C++26 |
85-
| `symmetric_matrix_vector_product` | xSYMV: 対称行列とベクトルの積を求める (function template) | C++26 |
85+
| [`symmetric_matrix_vector_product`](linalg/symmetric_matrix_vector_product.md) | xSYMV: 対称行列とベクトルの積を求める (function template) | C++26 |
8686
| `hermitian_matrix_vector_product` | xHEMV: ハミルトニアン行列とベクトルの積を求める (function template) | C++26 |
8787
| `triangular_matrix_vector_product` | xTRMV: 三角行列とベクトルの積を求める (function template) | C++26 |
8888
| `triangular_matrix_vector_solve` | xTRSV: 三角行列を係数とする行列方程式を解く (function template) | C++26 |
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# symmetric_matrix_vector_product
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-matrix InMat,
14+
class Triangle,
15+
in-vector InVec,
16+
out-vector OutVec>
17+
void symmetric_matrix_vector_product(InMat A,
18+
Triangle t,
19+
InVec x,
20+
OutVec y); // (1)
21+
22+
template<class ExecutionPolicy,
23+
in-matrix InMat,
24+
class Triangle,
25+
in-vector InVec,
26+
out-vector OutVec>
27+
void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
28+
InMat A,
29+
Triangle t,
30+
InVec x,
31+
OutVec y); // (2)
32+
33+
template<in-matrix InMat,
34+
class Triangle,
35+
in-vector InVec1,
36+
in-vector InVec2,
37+
out-vector OutVec>
38+
void symmetric_matrix_vector_product(
39+
InMat A,
40+
Triangle t,
41+
InVec1 x,
42+
InVec2 y,
43+
OutVec z); // (3)
44+
45+
template<class ExecutionPolicy,
46+
in-matrix InMat,
47+
class Triangle,
48+
in-vector InVec1,
49+
in-vector InVec2,
50+
out-vector OutVec>
51+
void symmetric_matrix_vector_product(
52+
ExecutionPolicy&& exec,
53+
InMat A,
54+
Triangle t,
55+
InVec1 x,
56+
InVec2 y,
57+
OutVec z); // (4)
58+
}
59+
```
60+
61+
62+
## 概要
63+
対称行列とベクトルの積を計算する。
64+
引数`t`は対称行列の成分が上三角にあるのか、それとも下三角にあるのかを示す。
65+
66+
- (1): $y \leftarrow Ax$
67+
- (2): (1)を指定された実行ポリシーで実行する。
68+
- (3): $z \leftarrow y + Ax$
69+
- (4): (3)を指定された実行ポリシーで実行する。
70+
71+
72+
## 適格要件
73+
- (1), (2), (3), (4): `InMat`が[`layout_blas_packed`](layout_blas_packed.md)を持つなら、レイアウトの`Triangle`テンプレート引数とこの関数の`Triangle`テンプレート引数が同じ型
74+
- (1), (2), (3), (4): [`compatible-static-extents`](compatible-static-extents.md)`<decltype(A), decltype(A)>(0, 1)`が`true` (つまり`A`が正方行列であること)
75+
- (1), (2), (3), (4): [`possibly-multipliable`](possibly-multipliable.md)`<decltype(A), decltype(x), decltype(y)>()`が`true`
76+
- (3), (4): [`possibly-addable`](possibly-addable.md)`<decltype(x),decltype(y),decltype(z)>()`が`true`
77+
78+
79+
## 事前条件
80+
- (1), (2), (3), (4): `A.extent(0) == A.extent(1)`
81+
- (1), (2), (3), (4): [`multipliable`](multipliable.md)`(A, x, y) == true`
82+
- (3), (4): [`addable`](addable.md)`(x, y, z) == true`
83+
84+
85+
## 効果
86+
対称行列の成分の位置を示す`t`を考慮した、対称行列とベクトルの積を計算する。
87+
88+
- (1), (2): $y \leftarrow Ax$
89+
- (3), (4): $z \leftarrow y + Ax$
90+
91+
92+
## 戻り値
93+
なし
94+
95+
96+
## 計算量
97+
$O(\verb|A.extent(1)|\times \verb|x.extent(0)|)$
98+
99+
100+
## 備考
101+
- (3), (4): `z`に`y`を入れても良い。
102+
103+
104+
## 例
105+
**[注意] 処理系にあるコンパイラで確認していないため、間違っているかもしれません。**
106+
107+
```cpp example
108+
#include <array>
109+
#include <iostream>
110+
#include <linalg>
111+
#include <mdspan>
112+
#include <vector>
113+
114+
template <class Vector>
115+
void print(const Vector& v, const std::string& name) {
116+
for (int i = 0; i < v.extent(0); ++i) {
117+
std::cout << name << "[" << i << "]" << " = " << v[i] << '\n';
118+
}
119+
}
120+
121+
int main()
122+
{
123+
constexpr size_t N = 4;
124+
constexpr size_t M = 4;
125+
126+
std::vector<double> A_vec(N*M);
127+
std::vector<double> x_vec(M);
128+
std::array<double, N> y_vec, z_vec;
129+
130+
std::mdspan<
131+
double,
132+
std::extents<size_t, N, M>,
133+
std::linalg::layout_blas_packed<
134+
std::linalg::upper_triangle_t,
135+
std::linalg::row_major_t>
136+
> A(A_vec.data());
137+
std::mdspan x(x_vec.data(), M);
138+
std::mdspan y(y_vec.data(), N);
139+
std::mdspan z(z_vec.data(), N);
140+
141+
for(int i = 0; i < A.extent(0); ++i) {
142+
for(int j = i; j < A.extent(1); ++j) {
143+
A[i,j] = A.extent(1) * i + j;
144+
}
145+
}
146+
147+
for(int j = 0; j < x.extent(0); ++j) {
148+
x[j] = j;
149+
}
150+
for(int i = 0; i < y.extent(0); ++i) {
151+
y[i] = -i;
152+
}
153+
154+
// (1)
155+
std::cout << "(1)\n";
156+
std::linalg::symmetric_matrix_vector_product(A, std::linalg::upper_triangle, x, y);
157+
print(y, "y");
158+
159+
// (2)
160+
std::cout << "(2)\n";
161+
std::linalg::symmetric_matrix_vector_product(std::execution::par, A, std::linalg::upper_triangle, x, y);
162+
print(y, "y");
163+
164+
// (3)
165+
std::cout << "(3)\n";
166+
std::linalg::symmetric_matrix_vector_product(A, std::linalg::upper_triangle, x, y, z);
167+
print(z, "z");
168+
169+
// (4)
170+
std::cout << "(4)\n";
171+
std::linalg::symmetric_matrix_vector_product(std::execution::par, A, std::linalg::upper_triangle, x, y, z);
172+
print(z, "z");
173+
174+
return 0;
175+
}
176+
```
177+
178+
179+
### 出力
180+
```
181+
(1)
182+
y[0] = 14
183+
y[1] = 38
184+
y[2] = 59
185+
y[3] = 74
186+
(2)
187+
y[0] = 14
188+
y[1] = 38
189+
y[2] = 59
190+
y[3] = 74
191+
(3)
192+
z[0] = 28
193+
z[1] = 76
194+
z[2] = 118
195+
z[3] = 148
196+
(4)
197+
z[0] = 28
198+
z[1] = 76
199+
z[2] = 118
200+
z[3] = 148
201+
```
202+
203+
204+
## バージョン
205+
### 言語
206+
- C++26
207+
208+
### 処理系
209+
- [Clang](/implementation.md#clang): ??
210+
- [GCC](/implementation.md#gcc): ??
211+
- [ICC](/implementation.md#icc): ??
212+
- [Visual C++](/implementation.md#visual_cpp): ??
213+
214+
215+
## 関連項目
216+
- [`execution`](/reference/execution.md)
217+
- [`mdspan`](/reference/mdspan.md)
218+
219+
220+
## 参照
221+
- [P1673R13 A free function linear algebra interface based on the BLAS](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1673r13.html)
222+
- [LAPACK: csymv](https://netlib.org/lapack/explore-html/db/d17/group__hemv_gab137e328e44dc1530ab0a93ff65c108a.html#gab137e328e44dc1530ab0a93ff65c108a)
223+

0 commit comments

Comments
 (0)