Skip to content

Commit ef67876

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

File tree

2 files changed

+226
-1
lines changed

2 files changed

+226
-1
lines changed

reference/linalg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ BLAS 1, 2, 3のアルゴリズムでテンプレートパラメータが特に
8383
|------|------|----------------|
8484
| [`matrix_vector_product`](linalg/matrix_vector_product.md) | xGEMV: 一般行列とベクトルの積を求める (function template) | C++26 |
8585
| [`symmetric_matrix_vector_product`](linalg/symmetric_matrix_vector_product.md) | xSYMV: 対称行列とベクトルの積を求める (function template) | C++26 |
86-
| `hermitian_matrix_vector_product` | xHEMV: ハミルトニアン行列とベクトルの積を求める (function template) | C++26 |
86+
| [`hermitian_matrix_vector_product`](linalg/hermitian_matrix_vector_product.md) | 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 |
8989
| `matrix_rank_1_update` | xGER, xGERU: 行列のRank-1更新 (function template) | C++26 |
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
# hermitian_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 hermitian_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 hermitian_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 hermitian_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 hermitian_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 <complex>
110+
#include <iostream>
111+
#include <linalg>
112+
#include <mdspan>
113+
#include <vector>
114+
115+
template <class Vector>
116+
void print(const Vector& v, const std::string& name) {
117+
for (int i = 0; i < v.extent(0); ++i) {
118+
std::cout << name << "[" << i << "]" << " = " << v[i] << '\n';
119+
}
120+
}
121+
122+
int main()
123+
{
124+
constexpr size_t N = 4;
125+
constexpr size_t M = 4;
126+
127+
std::vector<std::complex<double>> A_vec(N*M);
128+
std::vector<double> x_vec(M);
129+
std::array<double, N> y_vec, z_vec;
130+
131+
std::mdspan<
132+
double,
133+
std::extents<size_t, N, M>,
134+
std::linalg::layout_blas_packed<
135+
std::linalg::upper_triangle_t,
136+
std::linalg::row_major_t>
137+
> A(A_vec.data());
138+
std::mdspan x(x_vec.data(), M);
139+
std::mdspan y(y_vec.data(), N);
140+
std::mdspan z(z_vec.data(), N);
141+
142+
for(int i = 0; i < A.extent(0); ++i) {
143+
for(int j = i; j < A.extent(1); ++j) {
144+
A[i,j] = std::complex<double>(i, j);
145+
}
146+
}
147+
148+
for(int j = 0; j < x.extent(0); ++j) {
149+
x[j] = j;
150+
}
151+
152+
// (1)
153+
std::cout << "(1)\n";
154+
std::linalg::hermitian_matrix_vector_product(A, std::linalg::upper_triangle, x, y);
155+
print(y, "y");
156+
157+
// (2)
158+
std::cout << "(2)\n";
159+
std::linalg::hermitian_matrix_vector_product(std::execution::par, A, std::linalg::upper_triangle, x, y);
160+
print(y, "y");
161+
162+
for(int i = 0; i < y.extent(0); ++i) {
163+
y[i] = -i;
164+
}
165+
166+
// (3)
167+
std::cout << "(3)\n";
168+
std::linalg::hermitian_matrix_vector_product(A, std::linalg::upper_triangle, x, y, z);
169+
print(z, "z");
170+
171+
// (4)
172+
std::cout << "(4)\n";
173+
std::linalg::hermitian_matrix_vector_product(std::execution::par, A, std::linalg::upper_triangle, x, y, z);
174+
print(z, "z");
175+
176+
return 0;
177+
}
178+
```
179+
180+
181+
### 出力
182+
```
183+
(1)
184+
y[0] = (0,14)
185+
y[1] = (6,14)
186+
y[2] = (11,11)
187+
y[3] = (14,0)
188+
(2)
189+
y[0] = (0,14)
190+
y[1] = (6,14)
191+
y[2] = (11,11)
192+
y[3] = (14,0)
193+
(3)
194+
z[0] = (0,14)
195+
z[1] = (5,14)
196+
z[2] = (9,11)
197+
z[3] = (11,0)
198+
(4)
199+
z[0] = (0,14)
200+
z[1] = (5,14)
201+
z[2] = (9,11)
202+
z[3] = (11,0)
203+
```
204+
205+
206+
## バージョン
207+
### 言語
208+
- C++26
209+
210+
### 処理系
211+
- [Clang](/implementation.md#clang): ??
212+
- [GCC](/implementation.md#gcc): ??
213+
- [ICC](/implementation.md#icc): ??
214+
- [Visual C++](/implementation.md#visual_cpp): ??
215+
216+
217+
## 関連項目
218+
- [`execution`](/reference/execution.md)
219+
- [`mdspan`](/reference/mdspan.md)
220+
221+
222+
## 参照
223+
- [P1673R13 A free function linear algebra interface based on the BLAS](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1673r13.html)
224+
- [LAPACK: csymv](https://netlib.org/lapack/explore-html/db/d17/group__hemv_gab137e328e44dc1530ab0a93ff65c108a.html#gab137e328e44dc1530ab0a93ff65c108a)
225+

0 commit comments

Comments
 (0)