Concepts — 代数的コンセプト

概要

calx::concepts 名前空間は、抽象代数学の主要な構造を C++20 コンセプト として定義する。 群・環・体・ベクトル空間・ヒルベルト空間などの代数的要件をコンパイル時に検証でき、 テンプレート引数の型制約を明示的に表現できる。

  • コンパイル時型検証 — テンプレート引数が代数的要件を満たさない場合、明確なエラーメッセージが得られる
  • 階層的設計 — AdditiveMonoid → AdditiveGroup → Ring → Field のように、数学的な包含関係を反映
  • 40 以上のコンセプト — 基本演算、代数的構造、ベクトル空間、線形写像、数値型、行列・テンソル、代数・加群をカバー
  • ヘッダオンリー — リンク不要。#include するだけで使用可能
  • C++23 拡張SparseMatrixOf, BandMatrixOf, RealField, ComplexField などの追加コンセプト (C++23 モード)

数学的な公理 (結合律、交換律、分配法則など) はコンパイル時に検証できないため、 構文的要件 (演算子の存在、戻り値型の一致) のみを検査する。 意味的な正しさはユーザーの責任となる。

基本演算コンセプト

コンセプト要件
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() が定義済み Floatfloat/double は静的メソッド pi()/e() を持たないため適合しない。calx::Float など独自型向け

代数的構造

以下の包含関係が成り立つ:

$$\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 等) には適合しない。

「マーカー」について: 交換律・完備性・ゼロ因子の不在などの数学的性質はコンパイル時に検証できないため、これらのコンセプトは意図の表明 (マーカー) として機能する。 実行時チェックは行われず、型がその性質を満たすことはユーザーの責任となる。

ベクトル空間

ベクトル空間とその拡張。スカラー型 S のデフォルトは 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>

線形写像

コンセプト要件説明
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 longshortnumeric_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, calx::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

行列・テンソル

コンセプト要件説明
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() 帯行列

代数と加群

コンセプト要件説明
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 calx::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));

ベクトル空間のアルゴリズム

// 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;
}

環の上での多項式評価

// 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

四元数型の判定

// 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);
}

コンセプトによるオーバーロード

// 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);
}