numerics 0.1.0
Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1/// @file vector.hpp
2/// @brief Vector operations
3#pragma once
4
6#include "core/policy.hpp"
7#include "core/types.hpp"
8#include <algorithm>
9#include <memory>
10#include <type_traits>
11
12namespace num {
13
14/// @brief Dense vector with optional GPU storage, templated over scalar type T.
15///
16/// Typical aliases:
17/// - `num::Vector` = BasicVector<real> -- real-valued, full backend
18/// dispatch including GPU
19/// - `num::CVector` = BasicVector<cplx> -- complex-valued, sequential only
20/// (no GPU)
21///
22/// All member functions are defined inline so the template is usable across
23/// translation units without explicit instantiation.
24template <typename T> class BasicVector {
25public:
26 BasicVector() : n_(0), data_(nullptr) {}
27
28 explicit BasicVector(idx n) : n_(n), data_(new T[n]()) {}
29
30 BasicVector(idx n, T val) : n_(n), data_(new T[n]) {
31 std::fill_n(data_.get(), n_, val);
32 }
33
34 BasicVector(std::initializer_list<T> init)
35 : n_(init.size()), data_(new T[n_]) {
36 std::copy(init.begin(), init.end(), data_.get());
37 }
38
40 if constexpr (std::is_same_v<T, real>) {
41 if (d_data_)
42 cuda::free(d_data_);
43 }
44 }
45
46 BasicVector(const BasicVector &o) : n_(o.n_), data_(new T[n_]) {
47 std::copy_n(o.data_.get(), n_, data_.get());
48 }
49
51 : n_(o.n_), data_(std::move(o.data_)), d_data_(o.d_data_) {
52 o.n_ = 0;
53 o.d_data_ = nullptr;
54 }
55
57 if (this != &o) {
58 n_ = o.n_;
59 data_.reset(new T[n_]);
60 std::copy_n(o.data_.get(), n_, data_.get());
61 }
62 return *this;
63 }
64
66 if (this != &o) {
67 if constexpr (std::is_same_v<T, real>) {
68 if (d_data_)
69 cuda::free(d_data_);
70 }
71 n_ = o.n_;
72 data_ = std::move(o.data_);
73 d_data_ = o.d_data_;
74 o.n_ = 0;
75 o.d_data_ = nullptr;
76 }
77 return *this;
78 }
79
80 constexpr idx size() const noexcept { return n_; }
81
82 /// Satisfy the VecField concept: a Vector is its own underlying vector.
83 BasicVector &vec() { return *this; }
84 const BasicVector &vec() const { return *this; }
85
86 T *data() { return data_.get(); }
87 const T *data() const { return data_.get(); }
88
89 T &operator[](idx i) { return data_[i]; }
90 T operator[](idx i) const { return data_[i]; }
91
92 T *begin() { return data_.get(); }
93 T *end() { return data_.get() + n_; }
94 const T *begin() const { return data_.get(); }
95 const T *end() const { return data_.get() + n_; }
96
97 // GPU lifecycle (no-op for T != real)
98
99 void to_gpu() {
100 if constexpr (std::is_same_v<T, real>) {
101 if (!d_data_) {
102 d_data_ = cuda::alloc(n_);
103 cuda::to_device(d_data_, data_.get(), n_);
104 }
105 }
106 }
107
108 void to_cpu() {
109 if constexpr (std::is_same_v<T, real>) {
110 if (d_data_) {
111 cuda::to_host(data_.get(), d_data_, n_);
112 cuda::free(d_data_);
113 d_data_ = nullptr;
114 }
115 }
116 }
117
118 real *gpu_data() { return d_data_; }
119 const real *gpu_data() const { return d_data_; }
120 bool on_gpu() const { return d_data_ != nullptr; }
121
122private:
123 idx n_;
124 std::unique_ptr<T[]> data_;
125 real *d_data_ =
126 nullptr; // GPU mirror (real-typed); always nullptr for T != real
127};
128
129/// @brief Real-valued dense vector with full backend dispatch (CPU + GPU)
131
132/// @brief Complex-valued dense vector (sequential; no GPU)
134
135// Real-vector free functions (full backend dispatch)
136
137/// @brief v *= alpha
138void scale(Vector &v, real alpha, Backend b = default_backend);
139
140/// @brief z = x + y
141void add(const Vector &x, const Vector &y, Vector &z,
143
144/// @brief y += alpha * x
145void axpy(real alpha, const Vector &x, Vector &y, Backend b = default_backend);
146
147/// @brief dot product
148real dot(const Vector &x, const Vector &y, Backend b = default_backend);
149
150/// @brief Euclidean norm
151real norm(const Vector &x, Backend b = default_backend);
152
153// Strided views
154
155/// @brief Non-owning view of a flat Vector as an array of 2D points.
156///
157/// Many physics simulations pack 2D positions or velocities into a flat
158/// Vector with stride 2: element i has x = v[2i], y = v[2i+1].
159/// Vec2View provides named accessors that eliminate the raw index arithmetic
160/// without copying or reshaping the data.
161///
162/// Example:
163/// @code
164/// num::Vector q(2 * N); // flat storage: [x0,y0, x1,y1, ...]
165/// num::Vec2View pos{q};
166/// pos.x(i) = 1.0; // writes q[2*i]
167/// pos.y(i) = 2.0; // writes q[2*i+1]
168/// idx n = pos.size(); // = N
169/// @endcode
170struct Vec2View {
172
173 /// Number of 2D points (= v.size() / 2).
174 idx size() const noexcept { return v.size() / 2; }
175
176 real &x(idx i) noexcept { return v[2 * i]; }
177 real x(idx i) const noexcept { return v[2 * i]; }
178 real &y(idx i) noexcept { return v[2 * i + 1]; }
179 real y(idx i) const noexcept { return v[2 * i + 1]; }
180};
181
182/// @brief Read-only variant of Vec2View for const Vectors.
184 const Vector &v;
185
186 idx size() const noexcept { return v.size() / 2; }
187 real x(idx i) const noexcept { return v[2 * i]; }
188 real y(idx i) const noexcept { return v[2 * i + 1]; }
189};
190
191// Complex-vector free functions (sequential)
192
193/// @brief v *= alpha
194void scale(CVector &v, cplx alpha);
195
196/// @brief y += alpha * x
197void axpy(cplx alpha, const CVector &x, CVector &y);
198
199/// @brief Conjugate inner product <x, y> = Sigma conj(x_i) * y_i
200cplx dot(const CVector &x, const CVector &y);
201
202/// @brief Euclidean norm sqrt(Sigma |v_i|^2)
203real norm(const CVector &x);
204
205} // namespace num
Dense vector with optional GPU storage, templated over scalar type T.
Definition vector.hpp:24
const T * begin() const
Definition vector.hpp:94
const T * end() const
Definition vector.hpp:95
T & operator[](idx i)
Definition vector.hpp:89
const real * gpu_data() const
Definition vector.hpp:119
BasicVector(idx n, T val)
Definition vector.hpp:30
BasicVector & operator=(BasicVector &&o) noexcept
Definition vector.hpp:65
BasicVector & operator=(const BasicVector &o)
Definition vector.hpp:56
const T * data() const
Definition vector.hpp:87
bool on_gpu() const
Definition vector.hpp:120
T operator[](idx i) const
Definition vector.hpp:90
BasicVector(BasicVector &&o) noexcept
Definition vector.hpp:50
BasicVector(idx n)
Definition vector.hpp:28
const BasicVector & vec() const
Definition vector.hpp:84
real * gpu_data()
Definition vector.hpp:118
BasicVector & vec()
Satisfy the VecField concept: a Vector is its own underlying vector.
Definition vector.hpp:83
constexpr idx size() const noexcept
Definition vector.hpp:80
BasicVector(const BasicVector &o)
Definition vector.hpp:46
BasicVector(std::initializer_list< T > init)
Definition vector.hpp:34
Backend enum for linear algebra operations.
Core type definitions.
CUDA kernel wrappers.
void to_device(real *dst, const real *src, idx n)
Copy host to device.
void free(real *ptr)
Free device memory.
real * alloc(idx n)
Allocate device memory.
void to_host(real *dst, const real *src, idx n)
Copy device to host.
double real
Definition types.hpp:10
Backend
Selects which backend handles a linalg operation.
Definition policy.hpp:19
std::size_t idx
Definition types.hpp:11
void scale(Vector &v, real alpha, Backend b=default_backend)
v *= alpha
Definition vector.cpp:29
real dot(const Vector &x, const Vector &y, Backend b=default_backend)
dot product
Definition vector.cpp:79
real norm(const Vector &x, Backend b=default_backend)
Euclidean norm.
Definition vector.cpp:97
std::complex< real > cplx
Definition types.hpp:12
void axpy(real alpha, const Vector &x, Vector &y, Backend b=default_backend)
y += alpha * x
Definition vector.cpp:58
constexpr Backend default_backend
Definition policy.hpp:92
void add(const Vector &x, const Vector &y, Vector &z, Backend b=default_backend)
z = x + y
Definition vector.cpp:50
BasicVector< cplx > CVector
Complex-valued dense vector (sequential; no GPU)
Definition vector.hpp:133
Read-only variant of Vec2View for const Vectors.
Definition vector.hpp:183
const Vector & v
Definition vector.hpp:184
real x(idx i) const noexcept
Definition vector.hpp:187
real y(idx i) const noexcept
Definition vector.hpp:188
idx size() const noexcept
Definition vector.hpp:186
Non-owning view of a flat Vector as an array of 2D points.
Definition vector.hpp:170
real & y(idx i) noexcept
Definition vector.hpp:178
real x(idx i) const noexcept
Definition vector.hpp:177
idx size() const noexcept
Number of 2D points (= v.size() / 2).
Definition vector.hpp:174
Vector & v
Definition vector.hpp:171
real & x(idx i) noexcept
Definition vector.hpp:176
real y(idx i) const noexcept
Definition vector.hpp:179