Vector — Numeric Vector

Overview

Vector<T> is the dynamic-size numeric vector template class in calx. StaticVector<T,N> is the compile-time fixed-size variant. Both are header-only and require no additional library linking.

  • Expression templates — Expressions such as a + 2.0 * b produce no intermediate objects and are evaluated in a single loop at the point of assignment
  • SIMD auto-vectorization — SIMD packet evaluation via PacketTraits<T> (SSE/AVX2). 4-accumulator unrolling maximizes memory bandwidth
  • Block operations — Zero-copy views via head, tail, segment (Eigen-style)
  • BLAS Level-1 fusedaxpy and axpby execute in a single loop
  • VectorMap — Zero-copy view over external memory (equivalent to Eigen::Map)

Class Summary

ClassDescription
Vector<T>Dynamic-size vector. std::vector-based storage
StaticVector<T,N>Compile-time fixed-size vector. std::array<T,N>-based
VectorMap<T>Read-write view over external memory
ConstVectorMap<T>Read-only view over external memory

All reside in namespace calx. Both Vector and StaticVector inherit from VecExpr<Derived> (CRTP) and participate in expression templates.

Vector<T> Class

Constructors

SignatureDescription
Vector()Default construction. Empty vector (size = 0)
Vector(size_type n)Zero-initialized vector of size n
Vector(size_type n, const T& value)Size n, all elements initialized to value
Vector(size_type n, uninitialized_t)Size n, memory allocated only (values uninitialized). For POD type performance optimization
Vector(std::initializer_list<T> init)Construct from initializer list
Vector(const Vector&)Copy constructor
Vector(Vector&&) noexceptMove constructor
Vector(const VecExpr<E>& expr)Implicit conversion from expression template. Assigned via SIMD packet evaluation
Vector<double> v1;                        // Empty vector
Vector<double> v2(5);                     // Size 5, zero-initialized
Vector<double> v3(5, 1.0);               // Size 5, all elements 1.0
Vector<double> v4{1.0, 2.0, 3.0};        // Initializer list

Element Access

Member FunctionDescription
operator[](size_type i)Element reference (assert-based bounds check)
at(size_type i)Element reference (exception-based bounds check)
front()First element. Throws IndexError if empty
back()Last element. Throws IndexError if empty
data()Raw pointer to the internal buffer
Vector<double> v{10, 20, 30};
double a = v[0];      // 10 (assert-based bounds check)
double b = v.at(1);   // 20 (exception-based bounds check)
v[2] = 99;            // Assignment

Iterators

Member FunctionDescription
begin() / end()Mutable iterators
cbegin() / cend()Const iterators

Capacity

Member FunctionDescription
size()Number of elements
empty()Whether the vector is empty
capacity()Currently allocated capacity
reserve(size_type n)Pre-allocate capacity
resize(size_type n)Resize
resize(size_type n, const T& value)Resize (new elements initialized to value)
shrink_to_fit()Release excess capacity
clear()Remove all elements (size = 0)

Arithmetic Operations

OperationDescription
v += wVector addition (element-wise)
v -= wVector subtraction (element-wise)
v *= scalarScalar multiplication
v /= scalarScalar division (invalid_argument on division by zero)
v += exprCompound addition from expression template (SIMD packet evaluation)
v -= exprCompound subtraction from expression template (SIMD packet evaluation)
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}

Expression Template Operations

The following binary operators return expression template nodes and are evaluated in bulk at the point of assignment. No intermediate Vector is created.

ExpressionDescription
a + bVector addition
a - bVector subtraction
scalar * aScalar-vector multiplication
a * scalarVector-scalar multiplication
Vector<double> a{1, 2, 3}, b{4, 5, 6}, c{7, 8, 9};
// Evaluated without intermediate buffers (expression templates)
Vector<double> result = 2.0 * a + b - 0.5 * c;

Dot Product / Norms

Member FunctionDescription
T dot(const Vector& rhs) constDot product $\langle \mathbf{a}, \mathbf{b} \rangle = \sum a_i b_i$. SIMD 4-accumulator unrolling
T norm() constL2 norm $\|\mathbf{v}\| = \sqrt{\sum v_i^2}$
T norm_l1() constL1 norm $\|\mathbf{v}\|_1 = \sum |v_i|$
T norm_linf() const$L_\infty$ norm $\|\mathbf{v}\|_\infty = \max |v_i|$
T norm_lp(double p) constGeneral $L_p$ norm $\|\mathbf{v}\|_p = \left(\sum |v_i|^p\right)^{1/p}$. Requires $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

Normalization

Member FunctionDescription
Vector normalized() constReturns a normalized copy (zero vector if $\|\mathbf{v}\| = 0$)
void normalize()Normalize in-place
Vector<double> v{3, 4};
auto u = normalized(v);  // {0.6, 0.8}

Block Operations

Returns zero-copy views (VectorView / ConstVectorView). Writes through the view are reflected in the original vector.

Member FunctionDescription
head(size_type n)View of the first n elements
tail(size_type n)View of the last n elements
segment(size_type offset, size_type count)View of count elements starting at offset
Vector<double> v{10, 20, 30, 40, 50};
auto sub = v.segment(1, 3);  // {20, 30, 40} (zero-copy view)

Miscellaneous

Member FunctionDescription
void zero()Set all elements to zero
void assign(size_type n, const T& value)Resize to n and set all elements to value

StaticVector<T,N> Class

A compile-time fixed-size vector. Internal storage is std::array<T,N>. No heap allocation, ideal for small vectors (3D coordinates, quaternions, etc.).

Constructors

SignatureDescription
StaticVector()Default construction. All elements zero
StaticVector(const T& value)All elements initialized to value
StaticVector(std::initializer_list<T>)Construct from initializer list
StaticVector(const VecExpr<E>&)Construct from expression template

API

Provides the same interface as Vector<T>.

  • Element access: operator[], at, data
  • Iterators: begin, end, cbegin, cend
  • Capacity: size() (constexpr), empty()
  • Arithmetic: +=, -=, *=, /= (vector-vector + scalar + expression template)
  • Dot product / Norms: dot, norm, norm_l1, norm_linf, norm_lp
  • Normalization: normalized, normalize
  • Block operations: head, tail, segment
  • Miscellaneous: zero()

size() is constexpr, so the size is determined at compile time. capacity, reserve, resize, shrink_to_fit, and clear are not provided.

Free Functions

The following free functions work with both Vector<T> and StaticVector<T,N>.

Dot Product / Norms

FunctionDescription
T dot(a, b)Dot product $\sum a_i b_i$
T norm(v)L2 norm $\|\mathbf{v}\|$
T norm2(v)Alias for norm (for generic interfaces such as ODE solvers)
T norm_l1(v)L1 norm
T norm_linf(v)$L_\infty$ norm
T norm_lp(v, p)General $L_p$ norm
Vector<T> normalized(v)Normalized copy

norm and norm2 also accept VecExpr<E> (expression template nodes) directly, computing the norm via packet evaluation without materialization.

Cross Product

FunctionDescription
StaticVector<T,3> cross(a, b)3D cross product. StaticVector<T,3> only
StaticVector<double, 3> i{1, 0, 0}, j{0, 1, 0};
auto k = cross(i, j);  // {0, 0, 1}

BLAS Level-1 Fused Functions

No temporary objects are created; processing is done in a single loop. The compiler's SIMD auto-vectorization is effective.

FunctionDescription
void axpy(alpha, x, y)$\mathbf{y} \mathrel{+}= \alpha \mathbf{x}$ (equivalent to 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 and axpby have overloads for both Vector<T> and StaticVector<T,N>.

VectorMap / ConstVectorMap

View classes that wrap external contiguous memory as a vector without copying.

VectorMap<T>

MemberDescription
VectorMap(T* data, size_type size)Construct a view from an external buffer
size()Number of elements
data()Pointer to the buffer
operator[](i)Element reference (read-write)
operator Vector<T>() constCopy-convert to Vector
operator=(const Vector<T>&)Element-wise copy assignment from Vector

ConstVectorMap<T>

MemberDescription
ConstVectorMap(const T* data, size_type size)Construct a view from an external buffer
size()Number of elements
data()Const pointer to the buffer
operator[](i) constElement reference (read-only)
operator Vector<T>() constCopy-convert to Vector
double raw[] = {1.0, 2.0, 3.0};
auto v = calx::VectorMap<double>(raw, 3);
v[1] = 5.0;  // raw[1] is changed to 5.0
double data[] = {1, 2, 3, 4, 5};
ConstVectorMap<double> view(data, 5);  // Read-only view without copying
double s = dot(view, view);            // 55

Usage Examples

#include <math/core/vector.hpp>
#include <iostream>
using namespace calx;

int main() {
    // Constructors
    Vector<double> a{1.0, 2.0, 3.0};
    Vector<double> b{4.0, 5.0, 6.0};

    // Expression templates — no intermediate objects
    Vector<double> c = a + 2.0 * b;  // {9, 12, 15}

    // Dot product / Norms
    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

    // Normalization
    Vector<double> u = normalized(a);
    std::cout << "norm(normalized(a)) = " << norm(u) << std::endl;  // 1

    // StaticVector + cross product
    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;

    // Block operations
    Vector<double> v{10.0, 20.0, 30.0, 40.0, 50.0};
    auto h = v.head(3);       // [10, 20, 30] — zero-copy view
    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 (external memory view)
    double raw[] = {1.0, 2.0, 3.0};
    auto map = VectorMap<double>(raw, 3);
    map[0] = 99.0;  // raw[0] is changed to 99.0
}