Vectors are the fundamental building block of linear algebra, and Eigen makes working with them natural and efficient in C++. Whether you need a small, fixed-size 3D vector for geometric operations or a large, dynamic vector for data processing, Eigen provides the right type with a consistent API.
Vector Types
Eigen provides two categories of vector types:
Fixed-Size Vectors
Fixed-size vectors have their dimensions known at compile time. This enables:
- Stack allocation (no heap overhead)
- Compile-time size checks
- Maximum compiler optimization
Eigen::Vector2d // 2-element vector of double
Eigen::Vector3d // 3-element vector of double
Eigen::Vector4d // 4-element vector of double
Dynamic-Size Vectors
Dynamic vectors have their size determined at runtime:
Eigen::VectorXd // dynamic vector of double
Eigen::VectorXf // dynamic vector of float
Scalar Type Suffixes
Every Eigen vector type has a suffix indicating the scalar type:
| Suffix | C++ Type |
|---|---|
d | double |
f | float |
i | int |
cf | std::complex<float> |
cd | std::complex<double> |
Examples:
Eigen::Vector2d 2-element double (2x1 matrix of double)
Eigen::Vector3f 3-element float
Eigen::Vector4cd 4-element complex<double>
Eigen::VectorXd dynamic double
Eigen::VectorXf dynamic float
Eigen::Vector2cf 2-element complex<float>
Initializing Vectors
Zero Initialization
// Dynamic vector: 5 zeros
Eigen::VectorXd x = Eigen::VectorXd::Zero(5);
// x = [0, 0, 0, 0, 0]
// Fixed-size vector: always 3 zeros
Eigen::Vector3d v = Eigen::Vector3d::Zero();
// v = [0, 0, 0]
Comma Initialization
The comma initializer fills the vector element by element, left to right:
Eigen::Vector2d a;
a << 1.0, 2.0;
// a = [1.0, 2.0]
Eigen::VectorXd b(2);
b << 2.0, 3.0;
// b = [2.0, 3.0]
For fixed-size vectors, you can also use the constructor directly:
Eigen::Vector2d a(5.0, 6.0); // 2-element
Eigen::Vector3d b(5.0, 6.0, 7.0); // 3-element
Eigen::Vector4d c(5.0, 6.0, 7.0, 8.0); // 4-element
Other Initialization Methods
// All ones
Eigen::VectorXd ones = Eigen::VectorXd::Ones(4);
// [1, 1, 1, 1]
// Random values (uniform in [-1, 1])
Eigen::VectorXd rand = Eigen::VectorXd::Random(4);
// Constant value
Eigen::VectorXd constant = Eigen::VectorXd::Constant(4, 3.14);
// [3.14, 3.14, 3.14, 3.14]
// LinSpaced: evenly spaced values
Eigen::VectorXd linspace = Eigen::VectorXd::LinSpaced(5, 0.0, 1.0);
// [0.0, 0.25, 0.5, 0.75, 1.0]
Accessing Vector Elements
Eigen::Vector3d v(1.0, 2.0, 3.0);
// By index (0-based)
std::cout << v(0) << std::endl; // 1.0
std::cout << v(1) << std::endl; // 2.0
std::cout << v[2] << std::endl; // 3.0 (alternative syntax)
// Named accessors for small vectors
std::cout << v.x() << std::endl; // 1.0
std::cout << v.y() << std::endl; // 2.0
std::cout << v.z() << std::endl; // 3.0
Vector Operations
Eigen::Vector3d a(1.0, 2.0, 3.0);
Eigen::Vector3d b(4.0, 5.0, 6.0);
// Addition and subtraction
Eigen::Vector3d sum = a + b; // [5, 7, 9]
Eigen::Vector3d diff = b - a; // [3, 3, 3]
// Scalar multiplication
Eigen::Vector3d scaled = 2.0 * a; // [2, 4, 6]
// Dot product
double dot = a.dot(b); // 1*4 + 2*5 + 3*6 = 32
// Cross product (3D only)
Eigen::Vector3d cross = a.cross(b); // [-3, 6, -3]
// Norm (magnitude)
double norm = a.norm(); // sqrt(1+4+9) = sqrt(14)
double norm_sq = a.squaredNorm(); // 14
// Normalize (unit vector)
Eigen::Vector3d unit = a.normalized();
Merging Vectors
You can concatenate two vectors into a larger vector using the comma initializer:
Eigen::VectorXd vec1(3);
vec1 << 1.0, 2.0, 3.0;
Eigen::VectorXd vec2(2);
vec2 << 4.0, 5.0;
// Merge: create a new vector with both
Eigen::VectorXd vec_joined(vec1.size() + vec2.size());
vec_joined << vec1, vec2;
// vec_joined = [1, 2, 3, 4, 5]
Converting from STL Vector to Eigen Vector
A very common operation: you receive data in a std::vector and need to use it as an Eigen vector.
Simple Method: Map
#include <Eigen/Dense>
#include <vector>
int N = 100;
std::vector<float> v(N, 1.0f);
// Map the STL vector's memory as an Eigen vector (no copy!)
Eigen::VectorXf ev = Eigen::VectorXf::Map(&v[0], N);
// Generic version using v.size()
Eigen::VectorXf ev2 = Eigen::VectorXf::Map(&v[0], v.size());
Eigen::Map creates an Eigen matrix/vector that references existing memory. This is zero-copy and extremely efficient.
Converting from Eigen Vector to STL Vector
Direct Constructor
Eigen::VectorXd ev(5);
ev << 1.0, 2.0, 3.0, 4.0, 5.0;
// Method 1: constructor from pointer range
std::vector<double> stl_vec(ev.data(), ev.data() + ev.size());
// Method 2: resize and map
std::vector<double> stl_vec2;
stl_vec2.resize(ev.size());
Eigen::Map<Eigen::VectorXd>(stl_vec2.data(), stl_vec2.size()) = ev;
Generic Template Function
For reusable code that converts any Eigen column matrix to a std::vector:
template<typename T>
std::vector<T> EigenColumnToVector(
const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& matrix)
{
if (matrix.cols() != 1) {
throw std::invalid_argument("Matrix must have exactly one column");
}
std::vector<T> result;
result.resize(matrix.rows());
for (Eigen::Index i = 0; i < matrix.rows(); ++i) {
result[i] = matrix(i, 0);
}
return result;
}
Complete Example
#include <Eigen/Dense>
#include <iostream>
#include <vector>
int main() {
// Fixed-size vector
Eigen::Vector3d v1(1.0, 2.0, 3.0);
std::cout << "v1 = " << v1.transpose() << std::endl;
// Dynamic vector with zero initialization
Eigen::VectorXd v2 = Eigen::VectorXd::Zero(5);
std::cout << "v2 = " << v2.transpose() << std::endl;
// Comma initialization
Eigen::VectorXd v3(3);
v3 << 10.0, 20.0, 30.0;
std::cout << "v3 = " << v3.transpose() << std::endl;
// Dot product
std::cout << "v1 . v1 = " << v1.dot(v1) << std::endl; // 14
// Norm
std::cout << "||v1|| = " << v1.norm() << std::endl;
// Merge
Eigen::VectorXd merged(v1.size() + v3.size());
merged << v1, v3;
std::cout << "merged = " << merged.transpose() << std::endl;
// STL -> Eigen
std::vector<float> stl_data = {1.0f, 2.0f, 3.0f};
Eigen::VectorXf ev = Eigen::VectorXf::Map(&stl_data[0], stl_data.size());
std::cout << "ev from STL = " << ev.transpose() << std::endl;
// Eigen -> STL
std::vector<double> back(v1.data(), v1.data() + v1.size());
std::cout << "back to STL: " << back[0] << ", " << back[1] << ", " << back[2] << std::endl;
return 0;
}
Summary
Eigen Vector Quick Reference:
+------------------------+---------------------------------------------+
| Type | Description |
+------------------------+---------------------------------------------+
| Eigen::Vector2d/3d/4d | Fixed 2/3/4 element double vector |
| Eigen::VectorXd | Dynamic double vector |
| Eigen::VectorXf | Dynamic float vector |
| ::Zero(n) | Initialize to zeros |
| ::Ones(n) | Initialize to ones |
| ::Random(n) | Initialize to random values |
| v << a, b, c | Comma initializer |
| v(i) | Element access (0-indexed) |
| v.dot(u) | Dot product |
| v.cross(u) | Cross product (3D only) |
| v.norm() | Euclidean norm |
| v.normalized() | Unit vector |
| Map(&stl[0], n) | Zero-copy view of STL vector data |
+------------------------+---------------------------------------------+
Conclusion
Eigen's vector types provide an elegant and efficient API for numerical computing. Fixed-size vectors benefit from stack allocation and compile-time optimization. Dynamic vectors handle runtime-determined sizes with a consistent interface. The Map facility bridges the gap between Eigen and STL with zero copy overhead.
With this foundation in vector operations, you are ready to tackle the full matrix API and more advanced linear algebra operations available in Eigen.