Vector — 数値ベクトル
概要
Vector<T> は calx の動的サイズ数値ベクトルテンプレートクラスである。
StaticVector<T,N> はコンパイル時固定サイズの変種。
どちらもヘッダオンリーで、追加のライブラリリンクは不要。
- 式テンプレート —
a + 2.0 * b のような式は中間オブジェクトを生成せず、代入時に単一ループで評価
- SIMD 自動ベクタライズ —
PacketTraits<T> を通じた SIMD パケット評価 (SSE/AVX2)。4 アキュムレータ展開で帯域を最大化
- ブロック操作 —
head, tail, segment によるゼロコピービュー (Eigen スタイル)
- BLAS Level-1 融合 —
axpy, axpby を単一ループで実行
- VectorMap — 外部メモリへのゼロコピービュー (Eigen::Map 相当)
クラス一覧
| クラス | 説明 |
Vector<T> | 動的サイズベクトル。std::vector ベースのストレージ |
StaticVector<T,N> | コンパイル時固定サイズベクトル。std::array<T,N> ベース |
VectorMap<T> | 外部メモリへの読み書き可能なビュー |
ConstVectorMap<T> | 外部メモリへの読み取り専用ビュー |
すべて namespace calx に所属。Vector と StaticVector は VecExpr<Derived> (CRTP) を継承し、式テンプレートに参加する。
Vector<T> クラス
コンストラクタ
| シグネチャ | 説明 |
Vector() | デフォルト構築。空ベクトル (size = 0) |
Vector(size_type n) | サイズ n のゼロ初期化ベクトル |
Vector(size_type n, const T& value) | サイズ n、全要素を value で初期化 |
Vector(size_type n, uninitialized_t) | サイズ n、メモリ確保のみ (値は未初期化)。POD 型のパフォーマンス最適化用 |
Vector(std::initializer_list<T> init) | 初期化子リストから構築 |
Vector(const Vector&) | コピーコンストラクタ |
Vector(Vector&&) noexcept | ムーブコンストラクタ |
Vector(const VecExpr<E>& expr) | 式テンプレートからの暗黙変換。SIMD パケット評価で代入 |
要素アクセス
| メンバ関数 | 説明 |
operator[](size_type i) | 要素参照 (assert による範囲チェック) |
at(size_type i) | 要素参照 (例外による範囲チェック) |
front() | 先頭要素。空なら IndexError |
back() | 末尾要素。空なら IndexError |
data() | 内部バッファへの生ポインタ |
イテレータ
| メンバ関数 | 説明 |
begin() / end() | 可変イテレータ |
cbegin() / cend() | const イテレータ |
容量
| メンバ関数 | 説明 |
size() | 要素数 |
empty() | 空か |
capacity() | 確保済み容量 |
reserve(size_type n) | 容量を事前確保 |
resize(size_type n) | サイズ変更 |
resize(size_type n, const T& value) | サイズ変更 (新要素を value で初期化) |
shrink_to_fit() | 余分な容量を解放 |
clear() | 全要素を削除 (size = 0) |
算術演算
| 演算 | 説明 |
v += w | ベクトル加算 (要素ごと) |
v -= w | ベクトル減算 (要素ごと) |
v *= scalar | スカラー乗算 |
v /= scalar | スカラー除算 (ゼロ除算時 invalid_argument) |
v += expr | 式テンプレートからの複合加算 (SIMD パケット評価) |
v -= expr | 式テンプレートからの複合減算 (SIMD パケット評価) |
式テンプレート演算
以下の二項演算子は式テンプレートノードを返し、代入時に一括評価される。中間 Vector は生成されない。
| 式 | 説明 |
a + b | ベクトル加算 |
a - b | ベクトル減算 |
scalar * a | スカラー・ベクトル乗算 |
a * scalar | ベクトル・スカラー乗算 |
Vector<double> a{1.0, 2.0, 3.0};
Vector<double> b{4.0, 5.0, 6.0};
Vector<double> c = a + 2.0 * b; // 一時オブジェクトなしで評価
内積・ノルム
| メンバ関数 | 説明 |
T dot(const Vector& rhs) const | 内積 $\langle \mathbf{a}, \mathbf{b} \rangle = \sum a_i b_i$。SIMD 4 アキュムレータ展開 |
T norm() const | L2 ノルム $\|\mathbf{v}\| = \sqrt{\sum v_i^2}$ |
T norm_l1() const | L1 ノルム $\|\mathbf{v}\|_1 = \sum |v_i|$ |
T norm_linf() const | $L_\infty$ ノルム $\|\mathbf{v}\|_\infty = \max |v_i|$ |
T norm_lp(double p) const | 一般 $L_p$ ノルム $\|\mathbf{v}\|_p = \left(\sum |v_i|^p\right)^{1/p}$。$p \ge 1$ が必要 |
正規化
| メンバ関数 | 説明 |
Vector normalized() const | 正規化されたコピーを返す ($\|\mathbf{v}\| = 0$ のときゼロベクトル) |
void normalize() | 自身を正規化 (in-place) |
ブロック操作
ゼロコピービュー (VectorView / ConstVectorView) を返す。ビュー経由の書き込みは元のベクトルに反映される。
| メンバ関数 | 説明 |
head(size_type n) | 先頭 n 要素のビュー |
tail(size_type n) | 末尾 n 要素のビュー |
segment(size_type offset, size_type count) | 位置 offset から count 要素のビュー |
その他
| メンバ関数 | 説明 |
void zero() | 全要素をゼロに設定 |
void assign(size_type n, const T& value) | サイズ n、全要素を value に再設定 |
StaticVector<T,N> クラス
コンパイル時固定サイズのベクトル。内部ストレージは std::array<T,N>。
ヒープ割り当てなしで、小さいベクトル (3D 座標、クォータニオン等) に最適。
コンストラクタ
| シグネチャ | 説明 |
StaticVector() | デフォルト構築。全要素ゼロ |
StaticVector(const T& value) | 全要素を value で初期化 |
StaticVector(std::initializer_list<T>) | 初期化子リストから構築 |
StaticVector(const VecExpr<E>&) | 式テンプレートからの構築 |
API
Vector<T> と同様のインタフェースを提供する。
- 要素アクセス:
operator[], at, data
- イテレータ:
begin, end, cbegin, cend
- 容量:
size() (constexpr), empty()
- 算術演算:
+=, -=, *=, /= (Vector 同士 + スカラー + 式テンプレート)
- 内積・ノルム:
dot, norm, norm_l1, norm_linf, norm_lp
- 正規化:
normalized, normalize
- ブロック操作:
head, tail, segment
- その他:
zero()
size() は constexpr であり、コンパイル時にサイズが確定する。capacity, reserve, resize, shrink_to_fit, clear は提供されない。
フリー関数
以下のフリー関数は Vector<T> と StaticVector<T,N> の両方に対応する。
内積・ノルム
| 関数 | 説明 |
T dot(a, b) | 内積 $\sum a_i b_i$ |
T norm(v) | L2 ノルム $\|\mathbf{v}\|$ |
T norm2(v) | norm の別名 (ODE ソルバー等の汎用インタフェース用) |
T norm_l1(v) | L1 ノルム |
T norm_linf(v) | $L_\infty$ ノルム |
T norm_lp(v, p) | 一般 $L_p$ ノルム |
Vector<T> normalized(v) | 正規化されたコピー |
norm と norm2 は VecExpr<E> (式テンプレートノード) も直接受け付ける。具体化せずにパケット評価でノルムを計算。
外積
| 関数 | 説明 |
StaticVector<T,3> cross(a, b) | 3D 外積。StaticVector<T,3> 専用 |
BLAS Level-1 融合関数
一時オブジェクトを生成せず、単一ループで処理する。コンパイラの SIMD 自動ベクタライズが有効。
| 関数 | 説明 |
void axpy(alpha, x, y) | $\mathbf{y} \mathrel{+}= \alpha \mathbf{x}$ (DAXPY 相当) |
void axpby(alpha, x, beta, y, result) | $\mathbf{result} = \alpha \mathbf{x} + \beta \mathbf{y}$ (out-of-place) |
void axpby(alpha, x, beta, y) | $\mathbf{y} = \alpha \mathbf{x} + \beta \mathbf{y}$ (in-place) |
axpy と axpby は Vector<T> 版と StaticVector<T,N> 版の両方がある。
VectorMap / ConstVectorMap
外部メモリ上の連続配列をコピーなしでベクトルとして参照するビュークラス。
VectorMap<T>
| メンバ | 説明 |
VectorMap(T* data, size_type size) | 外部バッファからビューを構築 |
size() | 要素数 |
data() | バッファへのポインタ |
operator[](i) | 要素参照 (読み書き可能) |
operator Vector<T>() const | Vector へのコピー変換 |
operator=(const Vector<T>&) | Vector からの要素コピー代入 |
ConstVectorMap<T>
| メンバ | 説明 |
ConstVectorMap(const T* data, size_type size) | 外部バッファからビューを構築 |
size() | 要素数 |
data() | バッファへの const ポインタ |
operator[](i) const | 要素参照 (読み取り専用) |
operator Vector<T>() const | Vector へのコピー変換 |
double raw[] = {1.0, 2.0, 3.0};
auto v = calx::VectorMap<double>(raw, 3);
v[1] = 5.0; // raw[1] が 5.0 に変更される
使用例
#include <math/core/vector.hpp>
#include <iostream>
using namespace calx;
int main() {
// コンストラクタ
Vector<double> a{1.0, 2.0, 3.0};
Vector<double> b{4.0, 5.0, 6.0};
// 式テンプレート — 中間オブジェクトなし
Vector<double> c = a + 2.0 * b; // {9, 12, 15}
// 内積・ノルム
std::cout << "dot(a,b) = " << dot(a, b) << std::endl; // 32
std::cout << "norm(a) = " << norm(a) << std::endl; // 3.74166
std::cout << "norm_l1 = " << norm_l1(a) << std::endl; // 6
std::cout << "norm_inf = " << norm_linf(a) << std::endl; // 3
// 正規化
Vector<double> u = normalized(a);
std::cout << "norm(normalized(a)) = " << norm(u) << std::endl; // 1
// StaticVector + 外積
StaticVector<double, 3> x{1.0, 0.0, 0.0};
StaticVector<double, 3> y{0.0, 1.0, 0.0};
auto z = cross(x, y); // {0, 0, 1}
std::cout << "cross = [" << z[0] << ", " << z[1] << ", " << z[2] << "]" << std::endl;
// ブロック操作
Vector<double> v{10.0, 20.0, 30.0, 40.0, 50.0};
auto h = v.head(3); // [10, 20, 30] — ゼロコピービュー
auto t = v.tail(2); // [40, 50]
auto s = v.segment(1, 3); // [20, 30, 40]
// BLAS Level-1
Vector<double> p{1.0, 2.0, 3.0};
Vector<double> q{4.0, 5.0, 6.0};
axpy(2.0, p, q); // q = {6, 9, 12}
// VectorMap (外部メモリビュー)
double raw[] = {1.0, 2.0, 3.0};
auto map = VectorMap<double>(raw, 3);
map[0] = 99.0; // raw[0] が 99.0 に変更
}