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 パケット評価で代入
Vector<double> v1; // 空ベクトル
Vector<double> v2(5); // サイズ5、ゼロ初期化
Vector<double> v3(5, 1.0); // サイズ5、全要素1.0
Vector<double> v4{1.0, 2.0, 3.0}; // 初期化子リスト
要素アクセス
メンバ関数 説明
operator[](size_type i)要素参照 (assert による範囲チェック)
at(size_type i)要素参照 (例外による範囲チェック)
front()先頭要素。空なら IndexError
back()末尾要素。空なら IndexError
data()内部バッファへの生ポインタ
Vector<double> v{10, 20, 30};
double a = v[0]; // 10 (assert による範囲チェック)
double b = v.at(1); // 20 (例外による範囲チェック)
v[2] = 99; // 代入
イテレータ
メンバ関数 説明
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<double> a{1, 2, 3}, b{4, 5, 6};
auto c = a + b; // {5, 7, 9}
auto d = a - b; // {-3, -3, -3}
auto e = 2.0 * a; // {2, 4, 6}
auto f = a / 2.0; // {0.5, 1, 1.5}
式テンプレート演算
以下の二項演算子は式テンプレートノードを返し、代入時に一括評価される。中間 Vector は生成されない。
式 説明
a + bベクトル加算
a - bベクトル減算
scalar * aスカラー・ベクトル乗算
a * scalarベクトル・スカラー乗算
Vector<double> a{1, 2, 3}, b{4, 5, 6}, c{7, 8, 9};
// 中間バッファなしで評価 (式テンプレート)
Vector<double> result = 2.0 * a + b - 0.5 * c;
内積・ノルム
メンバ関数 説明
T dot(const Vector& rhs) const内積 $\langle \mathbf{a}, \mathbf{b} \rangle = \sum a_i b_i$。SIMD 4 アキュムレータ展開
T norm() constL2 ノルム $\|\mathbf{v}\| = \sqrt{\sum v_i^2}$
T norm_l1() constL1 ノルム $\|\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<double> a{1, 2, 3}, b{4, 5, 6};
double d = dot(a, b); // 32
double n = norm(a); // 3.74166...
double n1 = norm_l1(a); // 6
double ni = norm_linf(a); // 3
正規化
メンバ関数 説明
Vector normalized() const正規化されたコピーを返す ($\|\mathbf{v}\| = 0$ のときゼロベクトル)
void normalize()自身を正規化 (in-place)
Vector<double> v{3, 4};
auto u = normalized(v); // {0.6, 0.8}
ブロック操作
ゼロコピービュー (VectorView / ConstVectorView) を返す。ビュー経由の書き込みは元のベクトルに反映される。
メンバ関数 説明
head(size_type n)先頭 n 要素のビュー
tail(size_type n)末尾 n 要素のビュー
segment(size_type offset, size_type count)位置 offset から count 要素のビュー
Vector<double> v{10, 20, 30, 40, 50};
auto sub = v.segment(1, 3); // {20, 30, 40} (ゼロコピービュー)
その他
メンバ関数 説明
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> 専用
StaticVector<double, 3> i{1, 0, 0}, j{0, 1, 0};
auto k = cross(i, j); // {0, 0, 1}
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>() constVector へのコピー変換
operator=(const Vector<T>&)Vector からの要素コピー代入
ConstVectorMap<T>
メンバ 説明
ConstVectorMap(const T* data, size_type size)外部バッファからビューを構築
size()要素数
data()バッファへの const ポインタ
operator[](i) const要素参照 (読み取り専用)
operator Vector<T>() constVector へのコピー変換
double raw[] = {1.0, 2.0, 3.0};
auto v = calx::VectorMap<double>(raw, 3);
v[1] = 5.0; // raw[1] が 5.0 に変更される
double data[] = {1, 2, 3, 4, 5};
ConstVectorMap<double> view(data, 5); // コピーなしの読み取りビュー
double s = dot(view, view); // 55
使用例
#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 に変更
}