Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
Validation.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <janus/math/Arithmetic.hpp>
4#include <janus/math/Logic.hpp>
5#include <sstream>
6#include <string>
7#include <type_traits>
11
13
14// =============================================================================
15// Checks (Boolean)
16// =============================================================================
17
19template <typename Scalar> bool is_finite(const Scalar &x) {
20 if constexpr (std::is_same_v<Scalar, SymbolicScalar>) {
21 return true; // Symbolics are assumed finite/checked by solver
22 } else {
23 using std::isfinite;
24 return isfinite(x);
25 }
26}
27
30template <typename Scalar>
31auto is_in_range(const Scalar &x, const Scalar &min, const Scalar &max) {
32 return x >= min && x <= max;
33}
34
35// =============================================================================
36// Math Utilities
37// =============================================================================
38
40template <typename Scalar>
41Scalar clamp(const Scalar &x, const Scalar &min, const Scalar &max) {
42 // return min(max(x, min_val), max_val)
43 return janus::min(janus::max(x, min), max);
44}
45
46// =============================================================================
47// Assertions (Throws on failure)
48// =============================================================================
49
51template <typename Scalar>
52void assert_finite(const Scalar &x, const std::string &name) {
53 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
54 if (!is_finite(x)) {
55 std::ostringstream ss;
56 ss << name << " must be finite (got " << x << ").";
57 throw ValidationError(ss.str());
58 }
59 }
60}
61
63template <typename Scalar>
64void assert_positive(const Scalar &x, const std::string &name) {
65 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
66 if (x <= Scalar(0)) {
67 std::ostringstream ss;
68 ss << name << " must be positive (got " << x << ").";
69 throw ValidationError(ss.str());
70 }
71 }
72}
73
75template <typename Scalar>
76void assert_non_negative(const Scalar &x, const std::string &name) {
77 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
78 if (x < Scalar(0)) {
79 std::ostringstream ss;
80 ss << name << " must be non-negative (got " << x << ").";
81 throw ValidationError(ss.str());
82 }
83 }
84}
85
87template <typename Scalar>
88void assert_in_range(const Scalar &x, const std::string &name,
89 const Scalar &min_val, const Scalar &max_val) {
90 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
91 if (x < min_val || x > max_val) {
92 std::ostringstream ss;
93 ss << name << " must be in range [" << min_val << ", " << max_val
94 << "] (got " << x << ").";
95 throw ValidationError(ss.str());
96 }
97 }
98}
99
101template <typename Scalar>
102void assert_at_most(const Scalar &x, const std::string &name,
103 const Scalar &max_val) {
104 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
105 if (x > max_val) {
106 std::ostringstream ss;
107 ss << name << " must be at most " << max_val << " (got " << x
108 << ").";
109 throw ValidationError(ss.str());
110 }
111 }
112}
113
115template <typename Scalar>
116void assert_at_least(const Scalar &x, const std::string &name,
117 const Scalar &min_val) {
118 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
119 if (x < min_val) {
120 std::ostringstream ss;
121 ss << name << " must be at least " << min_val << " (got " << x
122 << ").";
123 throw ValidationError(ss.str());
124 }
125 }
126}
127
131template <typename VectorType>
132void assert_unit_quaternion(const VectorType &q, double tolerance = 1e-6) {
133 using Scalar = typename VectorType::Scalar;
134
135 if constexpr (!std::is_same_v<Scalar, SymbolicScalar>) {
136 Scalar norm_sq = q.squaredNorm();
137
138 using std::abs;
139 if (abs(norm_sq - Scalar(1.0)) > Scalar(tolerance)) {
140 std::ostringstream ss;
141 ss << "Quaternion must be unit magnitude (squared norm = "
142 << norm_sq << ", expected 1.0 ± " << tolerance << ").";
143 throw ValidationError(ss.str());
144 }
145 }
146}
147
148} // namespace vulcan::validation
Exception hierarchy for Vulcan aerospace library.
Validation errors (invalid input ranges, non-finite values).
Definition VulcanError.hpp:107
Definition Validation.hpp:12
Scalar clamp(const Scalar &x, const Scalar &min, const Scalar &max)
Clamp value to [min, max].
Definition Validation.hpp:41
void assert_in_range(const Scalar &x, const std::string &name, const Scalar &min_val, const Scalar &max_val)
Assert value is in range [min, max].
Definition Validation.hpp:88
void assert_unit_quaternion(const VectorType &q, double tolerance=1e-6)
Definition Validation.hpp:132
void assert_finite(const Scalar &x, const std::string &name)
Assert value is finite.
Definition Validation.hpp:52
void assert_at_least(const Scalar &x, const std::string &name, const Scalar &min_val)
Assert value is greater than or equal to min.
Definition Validation.hpp:116
bool is_finite(const Scalar &x)
Check if value is finite (not NaN or Inf).
Definition Validation.hpp:19
void assert_at_most(const Scalar &x, const std::string &name, const Scalar &max_val)
Assert value is less than or equal to max.
Definition Validation.hpp:102
auto is_in_range(const Scalar &x, const Scalar &min, const Scalar &max)
Definition Validation.hpp:31
void assert_positive(const Scalar &x, const std::string &name)
Assert value is positive (> 0).
Definition Validation.hpp:64
void assert_non_negative(const Scalar &x, const std::string &name)
Assert value is non-negative (>= 0).
Definition Validation.hpp:76