Vector<T> is the dynamic-size numeric vector template class in sangi.
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
Number of elements (reservation capacity for reserve; new size for resize)
value
const T&
Initial value for newly created elements when expanding
Arithmetic Operations
Operation
Description
v += w
Vector addition (element-wise)
v -= w
Vector subtraction (element-wise)
v *= scalar
Scalar multiplication
v /= scalar
Scalar division (invalid_argument on division by zero)
v += expr
Compound addition from expression template (SIMD packet evaluation)
v -= expr
Compound subtraction from expression template (SIMD packet evaluation)
Vector<double> a{1, 2, 3}, b{4, 5, 6};
Vector<double> c = a + b; // Prefer explicit Vector over auto to force ET evaluation
Vector<double> d = a - b;
Vector<double> e = 2.0 * a;
Vector<double> f = a / 2.0;
// Run output:
// c = {5, 7, 9}
// d = {-3, -3, -3}
// e = {2, 4, 6}
// f = {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.
Expression
Description
a + b
Vector addition
a - b
Vector subtraction
scalar * a
Scalar-vector multiplication
a * scalar
Vector-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;
Returns a normalized copy; returns the zero vector unchanged if $\|\mathbf{v}\| = 0$
void normalize()
Normalize in-place. No-op when $\|\mathbf{v}\| = 0$ (no exception is thrown)
Vector<double> v{3, 4};
auto u = normalized(v);
// Run output: u = {0.6, 0.8}, norm(u) = 1 (unit vector)
Block Operations
Returns zero-copy views (VectorView / ConstVectorView). Writes through the view are reflected in the original vector.
Member Function
Return Type
Description
head(size_type n)
VectorView<T> / ConstVectorView<T>
View of the first n elements
tail(size_type n)
VectorView<T> / ConstVectorView<T>
View of the last n elements
segment(size_type offset, size_type count)
VectorView<T> / ConstVectorView<T>
View of count elements starting at offset
Parameter
Type
Description
n
size_type
Number of elements to take
offset
size_type
Zero-based start position
count
size_type
Number of elements to take starting at offset
Vector<double> v{10, 20, 30, 40, 50};
auto h = v.head(2); // zero-copy view
auto t = v.tail(2);
auto s = v.segment(1, 3);
// Run output: head(2)={10, 20}, tail(2)={40, 50}, segment(1,3)={20, 30, 40}
// Note: writing through a view (e.g. s[0] = 99) also modifies the original v
Miscellaneous
Member Function
Return Type
Description
zero()
void
Set all elements to zero
assign(size_type n, const T& value)
void
Resize to n and set all elements to value
Parameter
Type
Description
n
size_type
Size after the reassignment
value
const T&
Value to assign to every element
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.).
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
Function
Description
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
Function
Description
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);
// Run output: k = {0, 0, 1} (= z axis unit vector)
// Right-handed: cross(x, y) = z (i × j = k)
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.
Function
Description
void axpy(alpha, x, y)
$\mathbf{y} \mathrel{+}= \alpha \mathbf{x}$ (equivalent to DAXPY)
axpy and axpby have overloads for both Vector<T> and StaticVector<T,N>.
Vector<double> x{1, 2, 3}, y{10, 20, 30};
axpy(2.0, x, y); // y += 2*x
// Run output: y = {12, 24, 36}
Vector<double> a{1, 2, 3}, b{4, 5, 6}, r(3);
axpby(2.0, a, 3.0, b, r); // r = 2a + 3b
// Run output: r = {14, 19, 24}
VectorMap / ConstVectorMap
View classes that wrap external contiguous memory as a vector without copying. Equivalent to Eigen::Map.
Lifetime is the caller's responsibility: VectorMap / ConstVectorMap do not own or extend the lifetime of the underlying buffer; they merely store a pointer and a size. Using a view after the buffer has been freed is undefined behaviour (use-after-free). The view's behaviour is also undefined if the buffer is reallocated (its address changes) or resized after the view was constructed.
VectorMap<T>
Member
Description
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>() const
Copy-convert to Vector
operator=(const Vector<T>&)
Element-wise copy assignment from Vector
ConstVectorMap<T>
Member
Description
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) const
Element reference (read-only)
operator Vector<T>() const
Copy-convert to Vector
double raw[] = {1.0, 2.0, 3.0};
sangi::VectorMap<double> v(raw, 3);
v[1] = 5.0;
// Run output: raw[1] is overwritten to 5.0 (write-through to original buffer)
double data[] = {1, 2, 3, 4, 5};
ConstVectorMap<double> view(data, 5); // read-only zero-copy view
// Note: dot() does not accept ConstVectorMap directly; convert to Vector first:
Vector<double> view_vec = view; // implicit conversion copies
double s = dot(view_vec, view_vec);
// Run output: s = 55 (= 1+4+9+16+25)