Concepts — 代数的コンセプト
概要
sangi::concepts 名前空間は、抽象代数学の主要な構造を C++20 コンセプト として定義する。
群・環・体・ベクトル空間・ヒルベルト空間などの代数的要件をコンパイル時に検証でき、
テンプレート引数の型制約を明示的に表現できる。
- コンパイル時型検証 — テンプレート引数が代数的要件を満たさない場合、明確なエラーメッセージが得られる
- 階層的設計 — AdditiveMonoid → AdditiveGroup → Ring → Field のように、数学的な包含関係を反映
- 40 以上のコンセプト — 基本演算、代数的構造、ベクトル空間、線形写像、数値型、行列・テンソル、代数・加群をカバー
- ヘッダオンリー — リンク不要。
#includeするだけで使用可能 - C++23 拡張 —
SparseMatrixOf,BandMatrixOf,RealField,ComplexFieldなどの追加コンセプト (C++23 モード)
数学的な公理 (結合律、交換律、分配法則など) はコンパイル時に検証できないため、 構文的要件 (演算子の存在、戻り値型の一致) のみを検査する。 意味的な正しさはユーザーの責任となる。
ヘッダ
#include <math/concepts/algebraic_concepts.hpp>
ヘッダオンリー。リンクするライブラリは不要。内部で <math/core/traits.hpp> をインクルードする。
名前空間: sangi::concepts
コンセプト階層
sangi の代数的コンセプトは数学的な包含関係を反映して階層化されている。 下図は主要な構造の包含関係を示す (矢印 A → B は「A は B の上位構造」、 すなわち B が A を満たすことを意味する)。
主要型の代数的構造
| 型 | Ring | IntegralDomain | Field | OrderedField | 備考 |
|---|---|---|---|---|---|
int / long long | ✓ | ✓ | ✗ | ✗ | 整域だが体ではない (乗法逆元なし) |
double / float | ✓ | ✓ | ✓ | ✓ | 順序体 |
sangi::Float | ✓ | ✓ | ✓ | ✓ | 多倍長浮動小数点 |
sangi::Complex<double> | ✓ | ✓ | ✓ | ✗ | 順序なし |
sangi::Rational<T> | ✓ | ✓ | ✓ | ✓ | 有理数体 |
sangi::Quaternion<double> | ✓ | ✗ | ✗ | ✗ | 除環 (非可換、 DivisionRing は満たす) |
sangi::Polynomial<double> (既定) | ✓ | ✓ | ✗ | ✗ | 整域。 一般には体ではない |
sangi::Matrix<double> | ✗ | ✗ | ✗ | ✗ | operator/ なし |
unsigned int | ✗ | ✗ | ✗ | ✗ | AdditiveGroup 不適合 (加法逆元が閉じない) |
基本演算コンセプト
| コンセプト | 要件 | 例 |
|---|---|---|
HasBasicArithmetic<T> |
+, -, *, /, 単項 - が定義済み |
double, float, Int, Float, Rational, Complex<double> |
Comparable<T> |
==, !=, <, <=, >, >= が定義済み |
double, int, Int, Float, Rational |
EqualityComparable<T> |
==, != のみ |
Complex<double>, Quaternion<double>, 全数値型 |
HasMathConstants<T> |
T::pi(), T::e() が定義済み |
Float。float/double は静的メソッド pi()/e() を持たないため適合しない。sangi::Float など独自型向け |
HasBasicArithmetic<T> 適合表
| 型 | 適合 | 備考 |
|---|---|---|
int / double / long double | ✓ | 組込み数値型 |
sangi::Float | ✓ | 多倍長浮動小数点 |
sangi::Complex<T> | ✓ | 複素数 |
sangi::Rational<T> | ✓ | 有理数 |
sangi::Quaternion<T> | ✓ | 四元数 (非可換だが 5 演算は閉じる) |
sangi::Polynomial<T> | ✓ (条件付き) | 既定では多項式除算の商を返すため適合。 SANGI_POLY_DIV_RATIONAL 定義時は operator/ が RationalFunction<T> を返すため不適合。 後述の注意を参照 |
sangi::Matrix<T> | ✗ | operator/ なし |
sangi::Vector<T> | ✗ | operator/ なし、 operator* なし |
std::string | ✗ | -, *, /, 単項 - なし |
operator/ 切替)
sangi::Polynomial<T> の operator/ はビルド設定で挙動が変わる:
- 既定: 多項式除算の商を返す (
Polynomial<T>)。HasBasicArithmeticを満たす。 SANGI_POLY_DIV_RATIONAL定義時: 有理関数RationalFunction<T>を返す。HasBasicArithmetic<Polynomial<T>>は満たさなくなる。
数学的にも Polynomial<T> は整域 (IntegralDomain) であり、 一般には体ではないため Field<Polynomial<T>> はビルド設定にかかわらず満たさない。
代数的構造
以下の包含関係が成り立つ:
$$\text{AdditiveMonoid} \subset \text{AdditiveGroup} \subset \text{AdditiveAbelianGroup}$$ $$\text{Ring} = \text{AdditiveAbelianGroup} \cap \text{MultiplicativeMonoid}$$ $$\text{Ring} \subset \text{CommutativeRing} \subset \text{IntegralDomain} \subset \text{Field} \subset \text{OrderedField}$$| コンセプト | 要件 | 例 |
|---|---|---|
AdditiveMonoid<T> |
a + b, T{0} (加法単位元) |
int, float, double, unsigned int, Int, Float |
AdditiveGroup<T> |
AdditiveMonoid + 単項 -a, a - b |
int, float, double, Int, Float |
AdditiveAbelianGroup<T> |
AdditiveGroup (交換律はマーカー) | int, float, double, Int, Float |
MultiplicativeMonoid<T> |
a * b, T{1} (乗法単位元) |
int, float, double, Int, Float |
MultiplicativeGroup<T> |
MultiplicativeMonoid + T{1} / a (乗法逆元) |
float, double, Float, Rational, Complex<double> |
MultiplicativeAbelianGroup<T> |
MultiplicativeGroup (交換律はマーカー) | float, double, Float, Rational |
Ring<T> |
AdditiveAbelianGroup + MultiplicativeMonoid | int, float, double, Int, Float, Rational |
CommutativeRing<T> |
Ring (乗法の交換律はマーカー) | int, float, double, Int, Float, Rational |
IntegralDomain<T> |
CommutativeRing (ゼロ因子なしはマーカー) | int, float, double, Int, Float, Rational |
DivisionRing<T> |
Ring + MultiplicativeGroup (非可換体を含む) | float, double, Quaternion<double>, Complex<double> |
Field<T> |
+, -, *, /, 単項-, T(0), T(1) |
double, float, Float, Rational, Complex<double> |
OrderedField<T> |
Field + <, <=, >, >= |
double, float, Float, Rational |
Scalar<T> |
Field<T> || std::integral<T> |
int, double, Float, Rational |
unsigned 型に関する注意:
unsigned int 等の符号なし整数型は AdditiveMonoid を満たすが、加法逆元 (-a) が数学的に閉じないため AdditiveGroup 以上の代数的構造 (Ring, Field 等) には適合しない。
「マーカー」について: 交換律・完備性・ゼロ因子の不在などの数学的性質はコンパイル時に検証できないため、これらのコンセプトは意図の表明 (マーカー) として機能する。 実行時チェックは行われず、型がその性質を満たすことはユーザーの責任となる。
Ring<T> 適合表
| 型 | 適合 | 備考 |
|---|---|---|
int / long long | ✓ | 整数環 $\mathbb{Z}$ |
double / sangi::Float | ✓ | 体は環の特殊化 |
sangi::Rational<T> | ✓ | 有理数 |
sangi::Complex<T> | ✓ | 複素数 |
sangi::Polynomial<T> (既定) | ✓ | 多項式環 |
sangi::Quaternion<T> | ✓ | 四元数 (非可換環、 CommutativeRing は不適合) |
unsigned int | ✗ | 加法逆元が閉じない (AdditiveGroup 不適合) |
sangi::Matrix<T> | ✗ | 形状が一般に異なるため numeric_traits の特殊化非対応 |
Field<T> 適合表
| 型 | 適合 | 備考 |
|---|---|---|
double / float / long double | ✓ | 有限精度の体 |
sangi::Float | ✓ | 多倍長浮動小数点 |
sangi::Rational<T> | ✓ | 有理数体 $\mathbb{Q}$ |
sangi::Complex<double> | ✓ | 複素数体 $\mathbb{C}$ |
int / long long | ✗ | 乗法逆元なし (整域) |
sangi::Quaternion<T> | ✗ | 非可換 (DivisionRing は適合) |
sangi::Polynomial<T> | ✗ | 整域だが体ではない (詳細は下記注意) |
sangi::Matrix<T> | ✗ | operator/ なし |
Polynomial と Field)
sangi::Polynomial<T> は 係数 T が体であっても、 多項式環 T[x] 自体は体ではない (一般に乗法逆元が存在しない)。 したがって Field<Polynomial<T>> はビルド設定にかかわらず満たさない。
商体に相当する sangi::RationalFunction<T> (= T[x] の分数体) が体であり、 SANGI_POLY_DIV_RATIONAL 定義時の Polynomial::operator/ はこちらに昇格する。 体の代数演算 (例: safe_inverse) を多項式で行いたい場合は RationalFunction<T> を直接使うのが推奨される。
DivisionRing<T> 適合表
| 型 | 適合 | 備考 |
|---|---|---|
double / float / sangi::Float | ✓ | 体は除環の特殊化 |
sangi::Complex<T> | ✓ | 複素数体 |
sangi::Rational<T> | ✓ | 有理数体 |
sangi::Quaternion<T> | ✓ | 非可換除環 (Field は不適合だが DivisionRing は満たす) |
int | ✗ | 乗法逆元なし |
sangi::Polynomial<T> | ✗ | 整域だが除環ではない |
OrderedField<T> 適合表
| 型 | 適合 | 備考 |
|---|---|---|
double / float / long double | ✓ | 実数の有限精度近似 |
sangi::Float | ✓ | 多倍長実数 |
sangi::Rational<T> | ✓ | 有理数体は順序体 |
sangi::Complex<T> | ✗ | 複素数には自然な全順序が存在しない |
sangi::Quaternion<T> | ✗ | 非可換かつ順序なし |
ベクトル空間
ベクトル空間とその拡張。 スカラー型 S のデフォルトは double。
テンプレート引数
| 引数 | 型 | 説明 |
|---|---|---|
V | typename | ベクトル型 |
S | typename | スカラー型 (デフォルト double) |
| コンセプト | 要件 | 例 |
|---|---|---|
VectorSpace<V, S> |
v + w, v - w, s * v, v * s, -v |
Vector<double>, std::array<double, N> |
InnerProductSpace<V, S> |
VectorSpace + inner_product(v, w) → S |
Vector<double> (inner_product 定義時) |
NormedVectorSpace<V, S> |
VectorSpace + norm(v) → S |
Vector<double> (norm 定義時) |
BanachSpace<V, S> |
NormedVectorSpace (完備性はマーカー — コンパイル時に完備性は検証できないため、意図の表明として機能する。実行時チェックは行われない) | $\mathbb{R}^n$, $\ell^p$ 空間 |
HilbertSpace<V, S> |
InnerProductSpace (完備性はマーカー — コンパイル時に完備性は検証できないため、意図の表明として機能する。実行時チェックは行われない) | $\mathbb{R}^n$, $\ell^2$ 空間 |
FiniteDimensionalVectorSpace<V, S> |
VectorSpace + v.size() → size_t |
Vector<double> |
VectorSpace<V, S> 適合表
| (V, S) | 適合 | 備考 |
|---|---|---|
(sangi::Vector<double>, double) | ✓ | 標準的なベクトル空間 |
(sangi::Vector<Complex<double>>, Complex<double>) | ✓ | 複素ベクトル空間 |
(std::array<double, N>, double) | ✓ | 固定長ベクトル |
(sangi::Matrix<double>, double) | ✓ | 行列もベクトル空間を成す |
(double, double) | ✓ | 1 次元ベクトル空間 |
(sangi::Vector<double>, int) | ✗ | int * Vector<double> の戻り型不一致 |
(std::string, double) | ✗ | スカラー乗法なし |
線形写像
テンプレート引数
| 引数 | 型 | 説明 |
|---|---|---|
F | typename | 写像オブジェクト型 (関数オブジェクト) |
V1 | typename | 定義域ベクトル空間 |
V2 | typename | 値域ベクトル空間 |
S | typename | 共通スカラー型 (デフォルト double) |
| コンセプト | 要件 | 説明 |
|---|---|---|
LinearMap<F, V1, V2, S> |
f(v) → V2, f(v + w) → V2, f(s * v) → V2 |
$f(\alpha v + \beta w) = \alpha f(v) + \beta f(w)$。V1, V2 は VectorSpace |
ConjugateLinearMap<F, V1, V2, S> |
LinearMap と同じ構文要件 | $f(\alpha v) = \bar{\alpha} f(v)$。共役斉次性はコンパイル時検証不可 |
数値型コンセプト
| コンセプト | 要件 | 例 |
|---|---|---|
Numeric<T> |
HasBasicArithmetic + std::abs, std::max, std::min |
short, int, float, double, unsigned int |
IntegerType<T> |
std::integral<T> && Ring<T>。Ring の要件で numeric_traits の特殊化が必要 |
int, long long。short は numeric_traits の特殊化がないため不適合。unsigned 型は AdditiveGroup 要件を満たさないため不適合 |
NonNegativeIntegerType<T> |
std::unsigned_integral<T> |
unsigned int, size_t, uint64_t 等。配列 index・サイズ・カウンタなど非負値を保証したい場面で使用。加法逆元が閉じないため Ring 以上には適合しない |
FloatingPointType<T> |
OrderedField<T> && !std::integral<T> |
float, double, long double, sangi::Float |
ComplexType<T> |
T::value_type, std::real, std::imag, std::abs, std::arg, std::conj |
std::complex<double>, std::complex<float> |
QuaternionType<T> |
T::value_type, q.w, q.x, q.y, q.z, q.conj(), q.norm(), q.inverse() |
Quaternion<double>, Quaternion<float> |
RationalType<T> |
Field<T> + r.numerator(), r.denominator() |
Rational |
行列・テンソル
テンプレート引数
| 引数 | 型 | 説明 |
|---|---|---|
M | typename | 行列型 |
V | typename | ベクトル型 |
T / S | typename | 要素型 (スカラー型) |
| コンセプト | 要件 | 説明 |
|---|---|---|
MatrixOf<M, T> |
M::value_type, m(i,j) → T, m.rows(), m.cols() |
任意の行列型。traits.hpp で定義 |
VectorOf<V, T> |
V::value_type, v[i] → T, v.size() |
任意のベクトル型。traits.hpp で定義 |
SquareMatrixOf<M, T> |
MatrixOf + m.is_square() |
正方行列 |
SymmetricMatrixOf<M, T> |
SquareMatrixOf (対称性はマーカー) | 対称行列。実行時検証が別途必要 |
OrthogonalMatrixOf<M, T> |
SquareMatrixOf (直交性はマーカー) | 直交行列 ($M^T M = I$) |
TensorOf<T, S> |
t.rank(), t.shape(i), t.size(), t(i,j) → S |
多次元テンソル |
SparseMatrixOf<M, T> C++23 |
MatrixOf + m.non_zeros() |
疎行列 |
BandMatrixOf<M, T> C++23 |
MatrixOf + m.lower_bandwidth(), m.upper_bandwidth() |
帯行列 |
MatrixOf<M, T> 適合表
| (M, T) | 適合 | 備考 |
|---|---|---|
(sangi::Matrix<double>, double) | ✓ | 密行列 |
(sangi::Matrix<Complex<double>>, Complex<double>) | ✓ | 複素密行列 |
(sangi::SparseMatrix<double>, double) | ✓ | 疎行列。 SparseMatrixOf も満たす |
(sangi::Matrix<double>, float) | ✗ | value_type 不一致 |
(sangi::Vector<double>, double) | ✗ | operator(i,j) なし |
(std::vector<std::vector<double>>, double) | ✗ | rows()/cols()/value_type なし |
代数と加群
テンプレート引数
| 引数 | 型 | 説明 |
|---|---|---|
M | typename | 加群型 |
R | typename | 係数環型 |
A / L | typename | 代数 / リー代数を成すベクトル空間型 |
F | typename | 係数体型 |
| コンセプト | 要件 | 説明 |
|---|---|---|
Module<M, R> |
AdditiveAbelianGroup<M> + Ring<R> + r * m, m * r |
加群 (ベクトル空間の一般化。スカラーが体ではなく環) |
Algebra<A, F> |
VectorSpace<A,F> + Ring<A> + f * (a * b) |
代数 (ベクトル空間に乗法構造を追加) |
AssociativeAlgebra<A, F> |
Algebra (結合律はマーカー) | 結合代数。行列環など |
LieAlgebra<L, F> |
VectorSpace<L,F> + a * b → L (リー積) |
リー代数。$\mathfrak{so}(3)$, $\mathfrak{se}(3)$ など |
使用例
体で制約された汎用関数
#include <math/concepts/algebraic_concepts.hpp>
using namespace sangi::concepts;
// Field を満たす任意の型で動作する逆元計算
template<Field T>
T safe_inverse(const T& x) {
if (x == T(0)) return T(0); // ゼロ除算回避
return T(1) / x;
}
// double, Float, Rational, Complex<double> で使用可能
auto inv_d = safe_inverse(3.14);
auto inv_r = safe_inverse(Rational(3, 7));
// 実行結果:
// inv_d = 0.318471337579618
// inv_r = 7/3
// safe_inverse(0.0) = 0 (ゼロガード発火)
ベクトル空間のアルゴリズム
// VectorSpace を満たす型に対する線形結合
template<typename V, typename S>
requires VectorSpace<V, S>
V linear_combination(S a, const V& v, S b, const V& w) {
return a * v + b * w;
}
// 実行結果:
// v = {1,2,3}, w = {4,5,6}, a = 2.0, b = 3.0
// linear_combination = {14, 19, 24}
環の上での多項式評価
// Ring を満たす任意の型に対する Horner 法
template<Ring T>
T horner(const std::vector<T>& coeffs, const T& x) {
T result = T{0};
for (auto it = coeffs.rbegin(); it != coeffs.rend(); ++it) {
result = result * x + *it;
}
return result;
}
// int, double, Int, Float, Rational で使用可能
std::vector<double> poly = {1.0, -2.0, 3.0}; // 3x^2 - 2x + 1
double val = horner(poly, 2.0); // = 9.0
// 実行結果: val = 9 (= 3·4 − 2·2 + 1)
四元数型の判定
// QuaternionType と DivisionRing を組み合わせた制約
template<typename T>
requires QuaternionType<T> && DivisionRing<T>
auto rotation_axis(const T& q) {
auto v_norm = std::sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
return std::make_tuple(q.x / v_norm, q.y / v_norm, q.z / v_norm);
}
// 実行結果:
// Quaternion(0, 1, 2, 2) → axis = (1/3, 2/3, 2/3)、 |axis| = 1
コンセプトによるオーバーロード
// OrderedField: 比較可能な体 (double, Float, Rational)
template<OrderedField T>
T clamp(const T& x, const T& lo, const T& hi) {
if (x < lo) return lo;
if (x > hi) return hi;
return x;
}
// Field: 比較不可の体も含む (Complex<double>)
template<Field T>
T midpoint(const T& a, const T& b) {
return (a + b) / T(2);
}
// 実行結果:
// clamp(2.5, 0, 1) = 1
// clamp(-0.3, 0, 1) = 0
// midpoint(1.0, 5.0) = 3
// midpoint(1+0i, 3+4i) = 2+2i
コンセプト判定は static_assert サニティチェックで確認できる。