Sleipnir C++ API
Loading...
Searching...
No Matches
variable.hpp
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <algorithm>
6#include <concepts>
7#include <cstddef>
8#include <initializer_list>
9#include <source_location>
10#include <type_traits>
11#include <utility>
12#include <vector>
13
14#include <Eigen/Core>
15#include <gch/small_vector.hpp>
16
17#include "sleipnir/autodiff/expression.hpp"
18#include "sleipnir/autodiff/expression_functions.hpp"
19#include "sleipnir/autodiff/expression_graph.hpp"
20#include "sleipnir/autodiff/expression_type.hpp"
21#include "sleipnir/autodiff/sleipnir_base.hpp"
22#include "sleipnir/util/assert.hpp"
23#include "sleipnir/util/concepts.hpp"
24
25#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
26#include "sleipnir/util/print.hpp"
27#endif
28
29namespace slp {
30
31// Forward declarations for friend declarations in Variable
32
33template <typename Scalar>
34class VariableMatrix;
35
36namespace detail {
37
38template <typename Scalar>
39VariableMatrix<Scalar> gradient_tree(
40 const detail::ExpressionGraph<Scalar>& top_list,
41 const VariableMatrix<Scalar>& wrt);
42
43} // namespace detail
44
45template <typename Scalar, int UpLo = Eigen::Lower | Eigen::Upper>
46 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
47class Hessian;
48
49template <typename Scalar>
50class Jacobian;
51
55template <typename Scalar_>
56class Variable : public SleipnirBase {
57 public:
59 using Scalar = Scalar_;
60
62 Variable() = default;
63
65 explicit constexpr Variable(std::nullptr_t) : expr{nullptr} {}
66
70 // NOLINTNEXTLINE (google-explicit-constructor)
72 requires(!MatrixLike<Scalar>)
73 : expr{detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(
74 value)} {}
75
79 // NOLINTNEXTLINE (google-explicit-constructor)
81 slp_assert(value.rows() == 1 && value.cols() == 1);
82 }
83
87 // NOLINTNEXTLINE (google-explicit-constructor)
88 Variable(std::floating_point auto value)
89 : expr{detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(
90 Scalar(value))} {}
91
95 // NOLINTNEXTLINE (google-explicit-constructor)
96 Variable(std::integral auto value)
97 : expr{detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(
98 Scalar(value))} {}
99
103 explicit Variable(const detail::ExpressionPtr<Scalar>& expr) : expr{expr} {}
104
108 explicit constexpr Variable(detail::ExpressionPtr<Scalar>&& expr)
109 : expr{std::move(expr)} {}
110
116 expr =
117 detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(value);
118 m_graph_initialized = false;
119
120 return *this;
121 }
122
127#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
128 if (!expr->is_leaf) {
129 auto location = std::source_location::current();
130 slp::println(
131 stderr,
132 "WARNING: {}:{}: {}: Modified the value of a dependent variable",
133 location.file_name(), location.line(), location.function_name());
134 }
135#endif
136 expr->val = Scalar(value);
137 }
138
143 if (!m_graph_initialized) {
144 m_graph = detail::topological_sort(expr);
145 m_graph_initialized = true;
146 }
147 detail::update_values(m_graph);
148
149 return Scalar(expr->val);
150 }
151
156 ExpressionType type() const { return expr->type(); }
157
163 template <ScalarLike LHS, SleipnirScalarLike<Scalar> RHS>
164 friend Variable<Scalar> operator*(const LHS& lhs, const RHS& rhs) {
165 return Variable{Variable<Scalar>{lhs}.expr * rhs.expr};
166 }
167
173 template <SleipnirScalarLike<Scalar> LHS, ScalarLike RHS>
174 friend Variable<Scalar> operator*(const LHS& lhs, const RHS& rhs) {
175 return Variable{lhs.expr * Variable<Scalar>{rhs}.expr};
176 }
177
184 const Variable<Scalar>& rhs) {
185 return Variable{lhs.expr * rhs.expr};
186 }
187
193 *this = *this * rhs;
194 return *this;
195 }
196
203 const Variable<Scalar>& rhs) {
204 return Variable{lhs.expr / rhs.expr};
205 }
206
212 *this = *this / rhs;
213 return *this;
214 }
215
222 const Variable<Scalar>& rhs) {
223 return Variable{lhs.expr + rhs.expr};
224 }
225
231 *this = *this + rhs;
232 return *this;
233 }
234
241 const Variable<Scalar>& rhs) {
242 return Variable{lhs.expr - rhs.expr};
243 }
244
250 *this = *this - rhs;
251 return *this;
252 }
253
258 return Variable{-lhs.expr};
259 }
260
265 return Variable{+lhs.expr};
266 }
267
268 private:
271 detail::make_expression_ptr<detail::DecisionVariableExpression<Scalar>>();
272
275 detail::ExpressionGraph<Scalar> m_graph;
276
278 bool m_graph_initialized = false;
279
280 template <typename Scalar>
281 friend Variable<Scalar> abs(const Variable<Scalar>& x);
282 template <typename Scalar>
283 friend Variable<Scalar> acos(const Variable<Scalar>& x);
284 template <typename Scalar>
285 friend Variable<Scalar> asin(const Variable<Scalar>& x);
286 template <typename Scalar>
287 friend Variable<Scalar> atan(const Variable<Scalar>& x);
288 template <typename Scalar>
289 friend Variable<Scalar> atan2(const ScalarLike auto& y,
290 const Variable<Scalar>& x);
291 template <typename Scalar>
292 friend Variable<Scalar> atan2(const Variable<Scalar>& y,
293 const ScalarLike auto& x);
294 template <typename Scalar>
295 friend Variable<Scalar> atan2(const Variable<Scalar>& y,
296 const Variable<Scalar>& x);
297 template <typename Scalar>
298 friend Variable<Scalar> cbrt(const Variable<Scalar>& x);
299 template <typename Scalar>
300 friend Variable<Scalar> cos(const Variable<Scalar>& x);
301 template <typename Scalar>
302 friend Variable<Scalar> cosh(const Variable<Scalar>& x);
303 template <typename Scalar>
304 friend Variable<Scalar> erf(const Variable<Scalar>& x);
305 template <typename Scalar>
306 friend Variable<Scalar> exp(const Variable<Scalar>& x);
307 template <typename Scalar>
308 friend Variable<Scalar> hypot(const ScalarLike auto& x,
309 const Variable<Scalar>& y);
310 template <typename Scalar>
311 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
312 const ScalarLike auto& y);
313 template <typename Scalar>
314 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
315 const Variable<Scalar>& y);
316 template <typename Scalar>
317 friend Variable<Scalar> if_else(
318 std::type_identity_t<bool (*)(Scalar a, Scalar b)> cond,
319 const Variable<Scalar>& a, const Variable<Scalar>& b,
320 const Variable<Scalar>& t, const Variable<Scalar>& f);
321 template <typename Scalar>
322 friend Variable<Scalar> log(const Variable<Scalar>& x);
323 template <typename Scalar>
324 friend Variable<Scalar> log10(const Variable<Scalar>& x);
325 template <typename Scalar>
326 friend Variable<Scalar> max(const ScalarLike auto& a,
327 const Variable<Scalar>& b);
328 template <typename Scalar>
329 friend Variable<Scalar> max(const Variable<Scalar>& a,
330 const ScalarLike auto& b);
331 template <typename Scalar>
332 friend Variable<Scalar> max(const Variable<Scalar>& a,
333 const Variable<Scalar>& b);
334 template <typename Scalar>
335 friend Variable<Scalar> min(const ScalarLike auto& a,
336 const Variable<Scalar>& b);
337 template <typename Scalar>
338 friend Variable<Scalar> min(const Variable<Scalar>& a,
339 const ScalarLike auto& b);
340 template <typename Scalar>
341 friend Variable<Scalar> min(const Variable<Scalar>& a,
342 const Variable<Scalar>& b);
343 template <typename Scalar>
344 friend Variable<Scalar> pow(const ScalarLike auto& base,
345 const Variable<Scalar>& power);
346 template <typename Scalar>
347 friend Variable<Scalar> pow(const Variable<Scalar>& base,
348 const ScalarLike auto& power);
349 template <typename Scalar>
350 friend Variable<Scalar> pow(const Variable<Scalar>& base,
351 const Variable<Scalar>& power);
352 template <typename Scalar>
353 friend Variable<Scalar> sign(const Variable<Scalar>& x);
354 template <typename Scalar>
355 friend Variable<Scalar> sin(const Variable<Scalar>& x);
356 template <typename Scalar>
357 friend Variable<Scalar> sinh(const Variable<Scalar>& x);
358 template <typename Scalar>
359 friend Variable<Scalar> sqrt(const Variable<Scalar>& x);
360 template <typename Scalar>
361 friend Variable<Scalar> tan(const Variable<Scalar>& x);
362 template <typename Scalar>
363 friend Variable<Scalar> tanh(const Variable<Scalar>& x);
364 template <typename Scalar>
365 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
366 const Variable<Scalar>& y,
367 const Variable<Scalar>& z);
368
369 template <typename Scalar>
370 friend VariableMatrix<Scalar> detail::gradient_tree(
371 const detail::ExpressionGraph<Scalar>& top_list,
372 const VariableMatrix<Scalar>& wrt);
373 template <typename Scalar, int UpLo>
374 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
375 friend class Hessian;
376 template <typename Scalar>
377 friend class Jacobian;
378};
379
380template <template <typename> typename T, typename Scalar>
381 requires SleipnirMatrixLike<T<Scalar>, Scalar>
382Variable(T<Scalar>) -> Variable<Scalar>;
383
384template <std::floating_point T>
385Variable(T) -> Variable<T>;
386
387template <std::integral T>
388Variable(T) -> Variable<T>;
389
394template <typename Scalar>
395Variable<Scalar> abs(const Variable<Scalar>& x) {
396 return Variable{detail::abs(x.expr)};
397}
398
403template <typename Scalar>
404Variable<Scalar> acos(const Variable<Scalar>& x) {
405 return Variable{detail::acos(x.expr)};
406}
407
412template <typename Scalar>
413Variable<Scalar> asin(const Variable<Scalar>& x) {
414 return Variable{detail::asin(x.expr)};
415}
416
421template <typename Scalar>
422Variable<Scalar> atan(const Variable<Scalar>& x) {
423 return Variable{detail::atan(x.expr)};
424}
425
431template <typename Scalar>
432Variable<Scalar> atan2(const ScalarLike auto& y, const Variable<Scalar>& x) {
433 return Variable{detail::atan2(Variable<Scalar>(y).expr, x.expr)};
434}
435
441template <typename Scalar>
442Variable<Scalar> atan2(const Variable<Scalar>& y, const ScalarLike auto& x) {
443 return Variable{detail::atan2(y.expr, Variable<Scalar>(x).expr)};
444}
445
451template <typename Scalar>
452Variable<Scalar> atan2(const Variable<Scalar>& y, const Variable<Scalar>& x) {
453 return Variable{detail::atan2(y.expr, x.expr)};
454}
455
460template <typename Scalar>
461Variable<Scalar> cbrt(const Variable<Scalar>& x) {
462 return Variable{detail::cbrt(x.expr)};
463}
464
469template <typename Scalar>
470Variable<Scalar> cos(const Variable<Scalar>& x) {
471 return Variable{detail::cos(x.expr)};
472}
473
478template <typename Scalar>
479Variable<Scalar> cosh(const Variable<Scalar>& x) {
480 return Variable{detail::cosh(x.expr)};
481}
482
487template <typename Scalar>
488Variable<Scalar> erf(const Variable<Scalar>& x) {
489 return Variable{detail::erf(x.expr)};
490}
491
496template <typename Scalar>
497Variable<Scalar> exp(const Variable<Scalar>& x) {
498 return Variable{detail::exp(x.expr)};
499}
500
506template <typename Scalar>
507Variable<Scalar> hypot(const ScalarLike auto& x, const Variable<Scalar>& y) {
508 return Variable{detail::hypot(Variable<Scalar>(x).expr, y.expr)};
509}
510
516template <typename Scalar>
517Variable<Scalar> hypot(const Variable<Scalar>& x, const ScalarLike auto& y) {
518 return Variable{detail::hypot(x.expr, Variable<Scalar>(y).expr)};
519}
520
526template <typename Scalar>
527Variable<Scalar> hypot(const Variable<Scalar>& x, const Variable<Scalar>& y) {
528 return Variable{detail::hypot(x.expr, y.expr)};
529}
530
543template <typename Scalar>
544Variable<Scalar> if_else(
545 std::type_identity_t<bool (*)(Scalar a, Scalar b)> cond,
546 const Variable<Scalar>& a, const Variable<Scalar>& b,
547 const Variable<Scalar>& t, const Variable<Scalar>& f) {
548 return Variable{detail::if_else(cond, a.expr, b.expr, t.expr, f.expr)};
549}
550
555template <typename Scalar>
556Variable<Scalar> log(const Variable<Scalar>& x) {
557 return Variable{detail::log(x.expr)};
558}
559
564template <typename Scalar>
565Variable<Scalar> log10(const Variable<Scalar>& x) {
566 return Variable{detail::log10(x.expr)};
567}
568
576template <typename Scalar>
577Variable<Scalar> max(const ScalarLike auto& a, const Variable<Scalar>& b) {
578 return Variable{detail::max(Variable<Scalar>(a).expr, b.expr)};
579}
580
588template <typename Scalar>
589Variable<Scalar> max(const Variable<Scalar>& a, const ScalarLike auto& b) {
590 return Variable{detail::max(a.expr, Variable<Scalar>(b).expr)};
591}
592
600template <typename Scalar>
601Variable<Scalar> max(const Variable<Scalar>& a, const Variable<Scalar>& b) {
602 return Variable{detail::max(a.expr, b.expr)};
603}
604
612template <typename Scalar>
613Variable<Scalar> min(const ScalarLike auto& a, const Variable<Scalar>& b) {
614 return Variable{detail::min(Variable<Scalar>(a).expr, b.expr)};
615}
616
624template <typename Scalar>
625Variable<Scalar> min(const Variable<Scalar>& a, const ScalarLike auto& b) {
626 return Variable{detail::min(a.expr, Variable<Scalar>(b).expr)};
627}
628
636template <typename Scalar>
637Variable<Scalar> min(const Variable<Scalar>& a, const Variable<Scalar>& b) {
638 return Variable{detail::min(a.expr, b.expr)};
639}
640
646template <typename Scalar>
647Variable<Scalar> pow(const ScalarLike auto& base,
648 const Variable<Scalar>& power) {
649 return Variable{detail::pow(Variable<Scalar>(base).expr, power.expr)};
650}
651
657template <typename Scalar>
658Variable<Scalar> pow(const Variable<Scalar>& base,
659 const ScalarLike auto& power) {
660 return Variable{detail::pow(base.expr, Variable<Scalar>(power).expr)};
661}
662
668template <typename Scalar>
669Variable<Scalar> pow(const Variable<Scalar>& base,
670 const Variable<Scalar>& power) {
671 return Variable{detail::pow(base.expr, power.expr)};
672}
673
678template <typename Scalar>
679Variable<Scalar> sign(const Variable<Scalar>& x) {
680 return Variable{detail::sign(x.expr)};
681}
682
687template <typename Scalar>
688Variable<Scalar> sin(const Variable<Scalar>& x) {
689 return Variable{detail::sin(x.expr)};
690}
691
696template <typename Scalar>
697Variable<Scalar> sinh(const Variable<Scalar>& x) {
698 return Variable{detail::sinh(x.expr)};
699}
700
705template <typename Scalar>
706Variable<Scalar> sqrt(const Variable<Scalar>& x) {
707 return Variable{detail::sqrt(x.expr)};
708}
709
714template <typename Scalar>
715Variable<Scalar> tan(const Variable<Scalar>& x) {
716 return Variable{detail::tan(x.expr)};
717}
718
723template <typename Scalar>
724Variable<Scalar> tanh(const Variable<Scalar>& x) {
725 return Variable{detail::tanh(x.expr)};
726}
727
734template <typename Scalar>
735Variable<Scalar> hypot(const Variable<Scalar>& x, const Variable<Scalar>& y,
736 const Variable<Scalar>& z) {
737 return Variable{detail::hypot(x.expr, y.expr, z.expr)};
738}
739
740// The standard form for equality constraints is c(x) = 0, and the standard form
741// for inequality constraints is c(x) ≥ 0. make_constraints() takes constraints
742// of the form lhs = rhs or lhs ≥ rhs and converts them to lhs - rhs = 0 or
743// lhs - rhs ≥ 0.
744
745template <typename Scalar, ScalarLike LHS, ScalarLike RHS>
746 requires SleipnirScalarLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
747auto make_constraints(LHS&& lhs, RHS&& rhs) {
748 gch::small_vector<Variable<Scalar>> constraints;
749 constraints.emplace_back(lhs - rhs);
750
751 return constraints;
752}
753
754template <typename Scalar, ScalarLike LHS, MatrixLike RHS>
755 requires SleipnirScalarLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
756auto make_constraints(LHS&& lhs, RHS&& rhs) {
757 gch::small_vector<Variable<Scalar>> constraints;
758 constraints.reserve(rhs.rows() * rhs.cols());
759
760 for (int row = 0; row < rhs.rows(); ++row) {
761 for (int col = 0; col < rhs.cols(); ++col) {
762 // Make right-hand side zero
763 constraints.emplace_back(lhs - rhs[row, col]);
764 }
765 }
766
767 return constraints;
768}
769
770template <typename Scalar, MatrixLike LHS, ScalarLike RHS>
771 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
772auto make_constraints(LHS&& lhs, RHS&& rhs) {
773 gch::small_vector<Variable<Scalar>> constraints;
774 constraints.reserve(lhs.rows() * lhs.cols());
775
776 for (int row = 0; row < lhs.rows(); ++row) {
777 for (int col = 0; col < lhs.cols(); ++col) {
778 // Make right-hand side zero
779 constraints.emplace_back(lhs[row, col] - rhs);
780 }
781 }
782
783 return constraints;
784}
785
786template <typename Scalar, MatrixLike LHS, MatrixLike RHS>
787 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
788auto make_constraints(LHS&& lhs, RHS&& rhs) {
789 slp_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
790
791 gch::small_vector<Variable<Scalar>> constraints;
792 constraints.reserve(lhs.rows() * lhs.cols());
793
794 for (int row = 0; row < lhs.rows(); ++row) {
795 for (int col = 0; col < lhs.cols(); ++col) {
796 // Make right-hand side zero
797 constraints.emplace_back(lhs[row, col] - rhs[row, col]);
798 }
799 }
800
801 return constraints;
802}
803
807template <typename Scalar>
810 gch::small_vector<Variable<Scalar>> constraints;
811
817 std::initializer_list<EqualityConstraints> equality_constraints) {
818 for (const auto& elem : equality_constraints) {
819 constraints.insert(constraints.end(), elem.constraints.begin(),
820 elem.constraints.end());
821 }
822 }
823
831 const std::vector<EqualityConstraints>& equality_constraints) {
832 for (const auto& elem : equality_constraints) {
833 constraints.insert(constraints.end(), elem.constraints.begin(),
834 elem.constraints.end());
835 }
836 }
837
845 template <typename LHS, typename RHS>
846 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
849 EqualityConstraints(LHS&& lhs, RHS&& rhs)
850 : constraints{make_constraints<Scalar>(lhs, rhs)} {}
851
853 // NOLINTNEXTLINE (google-explicit-constructor)
854 operator bool() {
855 return std::ranges::all_of(constraints, [](auto& constraint) {
856 return constraint.value() == Scalar(0);
857 });
858 }
859};
860
864template <typename Scalar>
867 gch::small_vector<Variable<Scalar>> constraints;
868
874 std::initializer_list<InequalityConstraints> inequality_constraints) {
875 for (const auto& elem : inequality_constraints) {
876 constraints.insert(constraints.end(), elem.constraints.begin(),
877 elem.constraints.end());
878 }
879 }
880
888 const std::vector<InequalityConstraints>& inequality_constraints) {
889 for (const auto& elem : inequality_constraints) {
890 constraints.insert(constraints.end(), elem.constraints.begin(),
891 elem.constraints.end());
892 }
893 }
894
903 template <typename LHS, typename RHS>
904 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
907 InequalityConstraints(LHS&& lhs, RHS&& rhs)
908 : constraints{make_constraints<Scalar>(lhs, rhs)} {}
909
911 // NOLINTNEXTLINE (google-explicit-constructor)
912 operator bool() {
913 return std::ranges::all_of(constraints, [](auto& constraint) {
914 return constraint.value() >= Scalar(0);
915 });
916 }
917};
918
923template <typename LHS, typename RHS>
924 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
925 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
926auto operator==(LHS&& lhs, RHS&& rhs) {
927 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
928}
929
934template <typename LHS, typename RHS>
935 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
936 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
937auto operator==(LHS&& lhs, RHS&& rhs) {
938 return EqualityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
939}
940
945template <typename LHS, typename RHS>
946 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
947 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
948auto operator==(LHS&& lhs, RHS&& rhs) {
949 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
950}
951
957template <typename LHS, typename RHS>
958 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
959 (ScalarLike<RHS> || MatrixLike<RHS>) &&
960 (SleipnirType<LHS> || SleipnirType<RHS>)
961auto operator<(LHS&& lhs, RHS&& rhs) {
962 return rhs >= lhs;
963}
964
970template <typename LHS, typename RHS>
971 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
972 (ScalarLike<RHS> || MatrixLike<RHS>) &&
973 (SleipnirType<LHS> || SleipnirType<RHS>)
974auto operator<=(LHS&& lhs, RHS&& rhs) {
975 return rhs >= lhs;
976}
977
983template <typename LHS, typename RHS>
984 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
985 (ScalarLike<RHS> || MatrixLike<RHS>) &&
986 (SleipnirType<LHS> || SleipnirType<RHS>)
987auto operator>(LHS&& lhs, RHS&& rhs) {
988 return lhs >= rhs;
989}
990
996template <typename LHS, typename RHS>
997 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
998 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
999auto operator>=(LHS&& lhs, RHS&& rhs) {
1000 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1001}
1002
1008template <typename LHS, typename RHS>
1009 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
1010 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1011auto operator>=(LHS&& lhs, RHS&& rhs) {
1012 return InequalityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
1013}
1014
1020template <typename LHS, typename RHS>
1021 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
1022 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1023auto operator>=(LHS&& lhs, RHS&& rhs) {
1024 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1025}
1026
1032template <typename L, typename X, typename U>
1033 requires(ScalarLike<L> || MatrixLike<L>) && SleipnirType<X> &&
1034 (ScalarLike<U> || MatrixLike<U>)
1035auto bounds(L&& l, X&& x, U&& u) {
1036 return InequalityConstraints{l <= x, x <= u};
1037}
1038
1039} // namespace slp
1040
1041namespace Eigen {
1042
1047template <typename Scalar>
1048struct NumTraits<slp::Variable<Scalar>> : NumTraits<Scalar> {
1057
1059 static constexpr int IsComplex = 0;
1061 static constexpr int IsInteger = 0;
1063 static constexpr int IsSigned = 1;
1065 static constexpr int RequireInitialization = 1;
1067 static constexpr int ReadCost = 1;
1069 static constexpr int AddCost = 3;
1071 static constexpr int MulCost = 3;
1072};
1073
1074} // namespace Eigen
Definition hessian.hpp:35
Definition intrusive_shared_ptr.hpp:27
Definition jacobian.hpp:31
Definition sleipnir_base.hpp:9
Definition variable_matrix.hpp:37
Definition variable.hpp:56
ExpressionType type() const
Definition variable.hpp:156
friend Variable< Scalar > operator*(const LHS &lhs, const RHS &rhs)
Definition variable.hpp:164
Variable(const detail::ExpressionPtr< Scalar > &expr)
Definition variable.hpp:103
Variable< Scalar > & operator/=(const Variable< Scalar > &rhs)
Definition variable.hpp:211
Variable< Scalar > & operator*=(const Variable< Scalar > &rhs)
Definition variable.hpp:192
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:221
void set_value(Scalar value)
Definition variable.hpp:126
friend Variable< Scalar > operator/(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:202
Variable(std::floating_point auto value)
Definition variable.hpp:88
constexpr Variable(detail::ExpressionPtr< Scalar > &&expr)
Definition variable.hpp:108
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs)
Definition variable.hpp:264
Variable(Scalar value)
Definition variable.hpp:71
constexpr Variable(std::nullptr_t)
Constructs an empty Variable.
Definition variable.hpp:65
Variable< Scalar > & operator=(ScalarLike auto value)
Definition variable.hpp:115
Variable()=default
Constructs a linear Variable with a value of zero.
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs)
Definition variable.hpp:257
friend Variable< Scalar > operator*(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:183
Variable(std::integral auto value)
Definition variable.hpp:96
Variable(SleipnirMatrixLike< Scalar > auto value)
Definition variable.hpp:80
Variable< Scalar > & operator+=(const Variable< Scalar > &rhs)
Definition variable.hpp:230
Scalar_ Scalar
Scalar type alias.
Definition variable.hpp:59
Scalar value()
Definition variable.hpp:142
Variable< Scalar > & operator-=(const Variable< Scalar > &rhs)
Definition variable.hpp:249
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:240
Definition concepts.hpp:18
Definition concepts.hpp:24
Definition concepts.hpp:33
Definition concepts.hpp:15
Definition variable.hpp:808
EqualityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:849
EqualityConstraints(std::initializer_list< EqualityConstraints > equality_constraints)
Definition variable.hpp:816
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar equality constraints.
Definition variable.hpp:810
EqualityConstraints(const std::vector< EqualityConstraints > &equality_constraints)
Definition variable.hpp:830
Definition variable.hpp:865
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar inequality constraints.
Definition variable.hpp:867
InequalityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:907
InequalityConstraints(const std::vector< InequalityConstraints > &inequality_constraints)
Definition variable.hpp:887
InequalityConstraints(std::initializer_list< InequalityConstraints > inequality_constraints)
Definition variable.hpp:873