Special Relativity in Financial Modeling 1.0.0
Lorentz transforms, spacetime classification, and geodesic price paths for quantitative finance
Loading...
Searching...
No Matches
n_asset_manifold.hpp
Go to the documentation of this file.
1#pragma once
2/**
3 * @file n_asset_manifold.hpp
4 * @brief N-Asset Lorentzian Manifold for Special Relativistic Financial Mechanics.
5 *
6 * Module: include/srfm/tensor/
7 * Stage: 4 — N-Asset Manifold
8 *
9 * ## Responsibility
10 * Represent a (N+1)-dimensional pseudo-Riemannian manifold with Lorentzian
11 * signature (-,+,+,...,+) where the spatial block is given by an N×N
12 * asset covariance matrix and the time-time component is -c_market².
13 *
14 * ## Metric Structure
15 * The metric tensor g_μν is a constant (N+1)×(N+1) matrix:
16 *
17 * g_00 = -c_market²
18 * g_0i = g_i0 = 0 for i ∈ {1,..,N}
19 * g_ij = Σ_ij for i,j ∈ {1,..,N}
20 *
21 * where Σ is the covariance matrix (Σ_ij = ρ_ij σ_i σ_j).
22 *
23 * ## Guarantees
24 * - Thread-safe: all methods are const and noexcept.
25 * - No raw pointers in the public API.
26 * - All fallible operations return std::optional.
27 * - Metric is constant (flat manifold); is_flat() always returns true.
28 *
29 * ## NOT Responsible For
30 * - Time-varying covariance (stochastic volatility models).
31 * - Cross-node synchronisation.
32 * - Persistence of manifold state.
33 */
34
35#include <optional>
36#include <string>
37#include <Eigen/Dense>
38
39namespace srfm::tensor {
40
41/**
42 * @brief (N+1)-dimensional Lorentzian manifold for N financial assets.
43 *
44 * The manifold dimension is n_assets + 1 (one time axis plus N price axes).
45 * The metric is assembled from a user-supplied N×N positive-definite
46 * covariance matrix and a market speed-of-light parameter c_market.
47 */
49public:
50 // ── Construction ─────────────────────────────────────────────────────────
51
52 /**
53 * @brief Construct an NAssetManifold directly.
54 *
55 * Prefer the factory @ref make() which validates inputs and returns
56 * std::nullopt on failure instead of constructing an invalid object.
57 *
58 * @param n_assets Number of asset price dimensions (spatial dimensions).
59 * @param covariance N×N positive-definite covariance matrix Σ.
60 * @param c_market Market speed-of-light parameter (must be > 0).
61 */
63 Eigen::MatrixXd covariance,
64 double c_market = 1.0) noexcept;
65
66 /**
67 * @brief Factory: validate inputs then construct.
68 *
69 * Validates:
70 * - n_assets >= 1
71 * - covariance is N×N
72 * - covariance is symmetric
73 * - covariance is positive-definite (all eigenvalues > 0)
74 * - c_market > 0
75 *
76 * @param n Number of assets.
77 * @param cov N×N covariance matrix.
78 * @param c_market Market speed of light (default 1.0).
79 * @return Constructed manifold or std::nullopt if inputs are invalid.
80 */
81 [[nodiscard]] static std::optional<NAssetManifold>
82 make(int n, Eigen::MatrixXd cov, double c_market = 1.0) noexcept;
83
84 // ── Dimensional accessors ─────────────────────────────────────────────────
85
86 /**
87 * @brief Returns the full manifold dimension = n_assets + 1.
88 *
89 * @return n_assets_ + 1.
90 */
91 [[nodiscard]] int dim() const noexcept;
92
93 /**
94 * @brief Returns the number of asset (spatial) dimensions.
95 *
96 * @return n_assets_.
97 */
98 [[nodiscard]] int n_assets() const noexcept;
99
100 // ── Metric tensor ─────────────────────────────────────────────────────────
101
102 /**
103 * @brief Evaluate the metric tensor at point x.
104 *
105 * Because this is a constant (flat) manifold the result does not depend
106 * on x. The parameter is accepted for API uniformity with curved manifolds.
107 *
108 * Returns a (N+1)×(N+1) matrix:
109 * row/col 0 → time component (g_00 = -c_market²)
110 * rows/cols 1..N → spatial block (g_ij = Σ_ij)
111 *
112 * @param x Coordinate vector of length dim() (unused for flat manifolds).
113 * @return The metric matrix, or std::nullopt if x has wrong dimension.
114 */
115 [[nodiscard]] std::optional<Eigen::MatrixXd>
116 metric_at(const Eigen::VectorXd& x) const noexcept;
117
118 /**
119 * @brief Evaluate the inverse metric g^μν at point x.
120 *
121 * Computed via LU decomposition of the metric matrix.
122 *
123 * @param x Coordinate vector of length dim().
124 * @return The inverse metric, or std::nullopt on failure.
125 */
126 [[nodiscard]] std::optional<Eigen::MatrixXd>
127 inverse_metric_at(const Eigen::VectorXd& x) const noexcept;
128
129 /**
130 * @brief Compute the squared line element ds² = g_μν dx^μ dx^ν.
131 *
132 * @param x Base point (unused for flat manifold, validated for dimension).
133 * @param dx Displacement vector of length dim().
134 * @return ds², or std::nullopt if dimensions are inconsistent.
135 */
136 [[nodiscard]] std::optional<double>
137 line_element_sq(const Eigen::VectorXd& x,
138 const Eigen::VectorXd& dx) const noexcept;
139
140 // ── Properties ────────────────────────────────────────────────────────────
141
142 /**
143 * @brief Returns true if the metric has no coordinate dependence.
144 *
145 * For NAssetManifold the metric is always constant, so this always
146 * returns true.
147 *
148 * @return true.
149 */
150 [[nodiscard]] bool is_flat() const noexcept;
151
152 /**
153 * @brief Returns the covariance matrix used to build the metric.
154 *
155 * @return The N×N covariance matrix, or std::nullopt on internal error.
156 */
157 [[nodiscard]] std::optional<Eigen::MatrixXd> covariance() const noexcept;
158
159 /**
160 * @brief Check structural compatibility with a 4D (N=3) manifold.
161 *
162 * Returns true if `other` has n_assets == 3 and this manifold's
163 * spatial block is consistent with being an extension of a 4D manifold.
164 * Concretely: returns true when other.n_assets() == 3 and
165 * this->n_assets() >= 3.
166 *
167 * @param other Manifold to compare against.
168 * @return true if compatible.
169 */
170 [[nodiscard]] bool reduces_to_4d(const NAssetManifold& other) const noexcept;
171
172 /**
173 * @brief Return the market speed-of-light parameter.
174 *
175 * @return c_market_.
176 */
177 [[nodiscard]] double c_market() const noexcept;
178
179 /**
180 * @brief Direct metric accessor (no coordinate argument).
181 *
182 * Returns the pre-built constant metric matrix.
183 *
184 * @return (N+1)×(N+1) metric tensor.
185 */
186 [[nodiscard]] const Eigen::MatrixXd& metric() const noexcept;
187
188 /**
189 * @brief Direct inverse metric accessor.
190 *
191 * Returns the pre-built inverse metric matrix.
192 *
193 * @return (N+1)×(N+1) inverse metric tensor.
194 */
195 [[nodiscard]] const Eigen::MatrixXd& inverse_metric() const noexcept;
196
197private:
198 // ── Internal helpers ──────────────────────────────────────────────────────
199
200 /**
201 * @brief Build the (N+1)×(N+1) metric matrix from stored covariance.
202 *
203 * Called once in the constructor.
204 */
205 void build_metric() noexcept;
206
207 /**
208 * @brief Build the inverse metric via full-pivot LU decomposition.
209 *
210 * Called once in the constructor after build_metric().
211 */
212 void build_inverse_metric() noexcept;
213
214 // ── Data members ──────────────────────────────────────────────────────────
215
216 int n_assets_; ///< Number of asset (spatial) dimensions.
217 double c_market_; ///< Market speed of light.
218 Eigen::MatrixXd covariance_; ///< N×N covariance matrix.
219 Eigen::MatrixXd metric_; ///< Pre-built (N+1)×(N+1) metric.
220 Eigen::MatrixXd inv_metric_; ///< Pre-built (N+1)×(N+1) inverse metric.
221 bool inv_valid_; ///< Whether inverse metric computation succeeded.
222};
223
224// ── Inline trivial accessors ──────────────────────────────────────────────────
225
226inline int NAssetManifold::dim() const noexcept {
227 return n_assets_ + 1;
228}
229
230inline int NAssetManifold::n_assets() const noexcept {
231 return n_assets_;
232}
233
234inline bool NAssetManifold::is_flat() const noexcept {
235 // Metric is constant — no coordinate dependence.
236 return true;
237}
238
239inline double NAssetManifold::c_market() const noexcept {
240 return c_market_;
241}
242
243inline const Eigen::MatrixXd& NAssetManifold::metric() const noexcept {
244 return metric_;
245}
246
247inline const Eigen::MatrixXd& NAssetManifold::inverse_metric() const noexcept {
248 return inv_metric_;
249}
250
251} // namespace srfm::tensor
(N+1)-dimensional Lorentzian manifold for N financial assets.
int n_assets() const noexcept
Returns the number of asset (spatial) dimensions.
std::optional< Eigen::MatrixXd > covariance() const noexcept
Returns the covariance matrix used to build the metric.
int dim() const noexcept
Returns the full manifold dimension = n_assets + 1.
const Eigen::MatrixXd & inverse_metric() const noexcept
Direct inverse metric accessor.
bool is_flat() const noexcept
Returns true if the metric has no coordinate dependence.
std::optional< Eigen::MatrixXd > inverse_metric_at(const Eigen::VectorXd &x) const noexcept
Evaluate the inverse metric g^μν at point x.
std::optional< Eigen::MatrixXd > metric_at(const Eigen::VectorXd &x) const noexcept
Evaluate the metric tensor at point x.
std::optional< double > line_element_sq(const Eigen::VectorXd &x, const Eigen::VectorXd &dx) const noexcept
Compute the squared line element ds² = g_μν dx^μ dx^ν.
static std::optional< NAssetManifold > make(int n, Eigen::MatrixXd cov, double c_market=1.0) noexcept
Factory: validate inputs then construct.
bool reduces_to_4d(const NAssetManifold &other) const noexcept
Check structural compatibility with a 4D (N=3) manifold.
double c_market() const noexcept
Return the market speed-of-light parameter.
const Eigen::MatrixXd & metric() const noexcept
Direct metric accessor (no coordinate argument).