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_graph.hpp"
19#include "sleipnir/autodiff/expression_type.hpp"
20#include "sleipnir/autodiff/sleipnir_base.hpp"
21#include "sleipnir/util/assert.hpp"
22#include "sleipnir/util/concepts.hpp"
23
24#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
25#include "sleipnir/util/print.hpp"
26#endif
27
28namespace slp {
29
30// Forward declarations for friend declarations in Variable
31
32template <typename Scalar>
33class VariableMatrix;
34
35namespace detail {
36
37template <typename Scalar>
38VariableMatrix<Scalar> gradient_tree(
39 const detail::ExpressionGraph<Scalar>& top_list,
40 const VariableMatrix<Scalar>& wrt);
41
42} // namespace detail
43
44template <typename Scalar, int UpLo = Eigen::Lower | Eigen::Upper>
45 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
46class Hessian;
47
48template <typename Scalar>
49class Jacobian;
50
54template <typename Scalar_>
55class Variable : public SleipnirBase {
56 public:
58 using Scalar = Scalar_;
59
61 Variable() = default;
62
64 explicit constexpr Variable(std::nullptr_t) : expr{nullptr} {}
65
69 // NOLINTNEXTLINE (google-explicit-constructor)
71 requires(!MatrixLike<Scalar>)
72 : expr{detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(
73 value)} {}
74
78 // NOLINTNEXTLINE (google-explicit-constructor)
80 slp_assert(value.rows() == 1 && value.cols() == 1);
81 }
82
86 // NOLINTNEXTLINE (google-explicit-constructor)
87 Variable(std::floating_point auto value)
88 : expr{detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(
89 Scalar(value))} {}
90
94 // NOLINTNEXTLINE (google-explicit-constructor)
95 Variable(std::integral auto value)
96 : expr{detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(
97 Scalar(value))} {}
98
102 explicit Variable(const detail::ExpressionPtr<Scalar>& expr) : expr{expr} {}
103
107 explicit constexpr Variable(detail::ExpressionPtr<Scalar>&& expr)
108 : expr{std::move(expr)} {}
109
115 expr =
116 detail::make_expression_ptr<detail::ConstantExpression<Scalar>>(value);
117 m_graph_initialized = false;
118
119 return *this;
120 }
121
126#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
127 if (!expr->is_leaf) {
128 auto location = std::source_location::current();
129 slp::println(
130 stderr,
131 "WARNING: {}:{}: {}: Modified the value of a dependent variable",
132 location.file_name(), location.line(), location.function_name());
133 }
134#endif
135 expr->val = Scalar(value);
136 }
137
142 if (!m_graph_initialized) {
143 m_graph = detail::topological_sort(expr);
144 m_graph_initialized = true;
145 }
146 detail::update_values(m_graph);
147
148 return Scalar(expr->val);
149 }
150
155 ExpressionType type() const { return expr->type(); }
156
162 template <ScalarLike LHS, SleipnirScalarLike<Scalar> RHS>
163 friend Variable<Scalar> operator*(const LHS& lhs, const RHS& rhs) {
164 return Variable{Variable<Scalar>{lhs}.expr * rhs.expr};
165 }
166
172 template <SleipnirScalarLike<Scalar> LHS, ScalarLike RHS>
173 friend Variable<Scalar> operator*(const LHS& lhs, const RHS& rhs) {
174 return Variable{lhs.expr * Variable<Scalar>{rhs}.expr};
175 }
176
183 const Variable<Scalar>& rhs) {
184 return Variable{lhs.expr * rhs.expr};
185 }
186
192 *this = *this * rhs;
193 return *this;
194 }
195
202 const Variable<Scalar>& rhs) {
203 return Variable{lhs.expr / rhs.expr};
204 }
205
211 *this = *this / rhs;
212 return *this;
213 }
214
221 const Variable<Scalar>& rhs) {
222 return Variable{lhs.expr + rhs.expr};
223 }
224
230 *this = *this + rhs;
231 return *this;
232 }
233
240 const Variable<Scalar>& rhs) {
241 return Variable{lhs.expr - rhs.expr};
242 }
243
249 *this = *this - rhs;
250 return *this;
251 }
252
257 return Variable{-lhs.expr};
258 }
259
264 return Variable{+lhs.expr};
265 }
266
267 private:
270 detail::make_expression_ptr<detail::DecisionVariableExpression<Scalar>>();
271
274 detail::ExpressionGraph<Scalar> m_graph;
275
277 bool m_graph_initialized = false;
278
279 template <typename Scalar>
280 friend Variable<Scalar> abs(const Variable<Scalar>& x);
281 template <typename Scalar>
282 friend Variable<Scalar> acos(const Variable<Scalar>& x);
283 template <typename Scalar>
284 friend Variable<Scalar> asin(const Variable<Scalar>& x);
285 template <typename Scalar>
286 friend Variable<Scalar> atan(const Variable<Scalar>& x);
287 template <typename Scalar>
288 friend Variable<Scalar> atan2(const ScalarLike auto& y,
289 const Variable<Scalar>& x);
290 template <typename Scalar>
291 friend Variable<Scalar> atan2(const Variable<Scalar>& y,
292 const ScalarLike auto& x);
293 template <typename Scalar>
294 friend Variable<Scalar> atan2(const Variable<Scalar>& y,
295 const Variable<Scalar>& x);
296 template <typename Scalar>
297 friend Variable<Scalar> cbrt(const Variable<Scalar>& x);
298 template <typename Scalar>
299 friend Variable<Scalar> cos(const Variable<Scalar>& x);
300 template <typename Scalar>
301 friend Variable<Scalar> cosh(const Variable<Scalar>& x);
302 template <typename Scalar>
303 friend Variable<Scalar> erf(const Variable<Scalar>& x);
304 template <typename Scalar>
305 friend Variable<Scalar> exp(const Variable<Scalar>& x);
306 template <typename Scalar>
307 friend Variable<Scalar> hypot(const ScalarLike auto& x,
308 const Variable<Scalar>& y);
309 template <typename Scalar>
310 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
311 const ScalarLike auto& y);
312 template <typename Scalar>
313 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
314 const Variable<Scalar>& y);
315 template <typename Scalar>
316 friend Variable<Scalar> if_else(
317 std::type_identity_t<bool (*)(Scalar a, Scalar b)> cond,
318 const Variable<Scalar>& a, const Variable<Scalar>& b,
319 const Variable<Scalar>& t, const Variable<Scalar>& f);
320 template <typename Scalar>
321 friend Variable<Scalar> log(const Variable<Scalar>& x);
322 template <typename Scalar>
323 friend Variable<Scalar> log10(const Variable<Scalar>& x);
324 template <typename Scalar>
325 friend Variable<Scalar> max(const ScalarLike auto& a,
326 const Variable<Scalar>& b);
327 template <typename Scalar>
328 friend Variable<Scalar> max(const Variable<Scalar>& a,
329 const ScalarLike auto& b);
330 template <typename Scalar>
331 friend Variable<Scalar> max(const Variable<Scalar>& a,
332 const Variable<Scalar>& b);
333 template <typename Scalar>
334 friend Variable<Scalar> min(const ScalarLike auto& a,
335 const Variable<Scalar>& b);
336 template <typename Scalar>
337 friend Variable<Scalar> min(const Variable<Scalar>& a,
338 const ScalarLike auto& b);
339 template <typename Scalar>
340 friend Variable<Scalar> min(const Variable<Scalar>& a,
341 const Variable<Scalar>& b);
342 template <typename Scalar>
343 friend Variable<Scalar> pow(const ScalarLike auto& base,
344 const Variable<Scalar>& power);
345 template <typename Scalar>
346 friend Variable<Scalar> pow(const Variable<Scalar>& base,
347 const ScalarLike auto& power);
348 template <typename Scalar>
349 friend Variable<Scalar> pow(const Variable<Scalar>& base,
350 const Variable<Scalar>& power);
351 template <typename Scalar>
352 friend Variable<Scalar> sign(const Variable<Scalar>& x);
353 template <typename Scalar>
354 friend Variable<Scalar> sin(const Variable<Scalar>& x);
355 template <typename Scalar>
356 friend Variable<Scalar> sinh(const Variable<Scalar>& x);
357 template <typename Scalar>
358 friend Variable<Scalar> sqrt(const Variable<Scalar>& x);
359 template <typename Scalar>
360 friend Variable<Scalar> tan(const Variable<Scalar>& x);
361 template <typename Scalar>
362 friend Variable<Scalar> tanh(const Variable<Scalar>& x);
363 template <typename Scalar>
364 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
365 const Variable<Scalar>& y,
366 const Variable<Scalar>& z);
367
368 template <typename Scalar>
369 friend VariableMatrix<Scalar> detail::gradient_tree(
370 const detail::ExpressionGraph<Scalar>& top_list,
372 template <typename Scalar, int UpLo>
373 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
374 friend class Hessian;
375 template <typename Scalar>
376 friend class Jacobian;
377};
378
379template <template <typename> typename T, typename Scalar>
380 requires SleipnirMatrixLike<T<Scalar>, Scalar>
381Variable(T<Scalar>) -> Variable<Scalar>;
382
383template <std::floating_point T>
384Variable(T) -> Variable<T>;
385
386template <std::integral T>
387Variable(T) -> Variable<T>;
388
393template <typename Scalar>
394Variable<Scalar> abs(const Variable<Scalar>& x) {
395 return Variable{detail::abs(x.expr)};
396}
397
402template <typename Scalar>
403Variable<Scalar> acos(const Variable<Scalar>& x) {
404 return Variable{detail::acos(x.expr)};
405}
406
411template <typename Scalar>
412Variable<Scalar> asin(const Variable<Scalar>& x) {
413 return Variable{detail::asin(x.expr)};
414}
415
420template <typename Scalar>
421Variable<Scalar> atan(const Variable<Scalar>& x) {
422 return Variable{detail::atan(x.expr)};
423}
424
430template <typename Scalar>
431Variable<Scalar> atan2(const ScalarLike auto& y, const Variable<Scalar>& x) {
432 return Variable{detail::atan2(Variable<Scalar>(y).expr, x.expr)};
433}
434
440template <typename Scalar>
441Variable<Scalar> atan2(const Variable<Scalar>& y, const ScalarLike auto& x) {
442 return Variable{detail::atan2(y.expr, Variable<Scalar>(x).expr)};
443}
444
450template <typename Scalar>
451Variable<Scalar> atan2(const Variable<Scalar>& y, const Variable<Scalar>& x) {
452 return Variable{detail::atan2(y.expr, x.expr)};
453}
454
459template <typename Scalar>
460Variable<Scalar> cbrt(const Variable<Scalar>& x) {
461 return Variable{detail::cbrt(x.expr)};
462}
463
468template <typename Scalar>
469Variable<Scalar> cos(const Variable<Scalar>& x) {
470 return Variable{detail::cos(x.expr)};
471}
472
477template <typename Scalar>
478Variable<Scalar> cosh(const Variable<Scalar>& x) {
479 return Variable{detail::cosh(x.expr)};
480}
481
486template <typename Scalar>
487Variable<Scalar> erf(const Variable<Scalar>& x) {
488 return Variable{detail::erf(x.expr)};
489}
490
495template <typename Scalar>
496Variable<Scalar> exp(const Variable<Scalar>& x) {
497 return Variable{detail::exp(x.expr)};
498}
499
505template <typename Scalar>
506Variable<Scalar> hypot(const ScalarLike auto& x, const Variable<Scalar>& y) {
507 return Variable{detail::hypot(Variable<Scalar>(x).expr, y.expr)};
508}
509
515template <typename Scalar>
516Variable<Scalar> hypot(const Variable<Scalar>& x, const ScalarLike auto& y) {
517 return Variable{detail::hypot(x.expr, Variable<Scalar>(y).expr)};
518}
519
525template <typename Scalar>
526Variable<Scalar> hypot(const Variable<Scalar>& x, const Variable<Scalar>& y) {
527 return Variable{detail::hypot(x.expr, y.expr)};
528}
529
542template <typename Scalar>
543Variable<Scalar> if_else(
544 std::type_identity_t<bool (*)(Scalar a, Scalar b)> cond,
545 const Variable<Scalar>& a, const Variable<Scalar>& b,
546 const Variable<Scalar>& t, const Variable<Scalar>& f) {
547 return Variable{detail::if_else(cond, a.expr, b.expr, t.expr, f.expr)};
548}
549
554template <typename Scalar>
555Variable<Scalar> log(const Variable<Scalar>& x) {
556 return Variable{detail::log(x.expr)};
557}
558
563template <typename Scalar>
564Variable<Scalar> log10(const Variable<Scalar>& x) {
565 return Variable{detail::log10(x.expr)};
566}
567
575template <typename Scalar>
576Variable<Scalar> max(const ScalarLike auto& a, const Variable<Scalar>& b) {
577 return Variable{detail::max(Variable<Scalar>(a).expr, b.expr)};
578}
579
587template <typename Scalar>
588Variable<Scalar> max(const Variable<Scalar>& a, const ScalarLike auto& b) {
589 return Variable{detail::max(a.expr, Variable<Scalar>(b).expr)};
590}
591
599template <typename Scalar>
600Variable<Scalar> max(const Variable<Scalar>& a, const Variable<Scalar>& b) {
601 return Variable{detail::max(a.expr, b.expr)};
602}
603
611template <typename Scalar>
612Variable<Scalar> min(const ScalarLike auto& a, const Variable<Scalar>& b) {
613 return Variable{detail::min(Variable<Scalar>(a).expr, b.expr)};
614}
615
623template <typename Scalar>
624Variable<Scalar> min(const Variable<Scalar>& a, const ScalarLike auto& b) {
625 return Variable{detail::min(a.expr, Variable<Scalar>(b).expr)};
626}
627
635template <typename Scalar>
636Variable<Scalar> min(const Variable<Scalar>& a, const Variable<Scalar>& b) {
637 return Variable{detail::min(a.expr, b.expr)};
638}
639
645template <typename Scalar>
646Variable<Scalar> pow(const ScalarLike auto& base,
647 const Variable<Scalar>& power) {
648 return Variable{detail::pow(Variable<Scalar>(base).expr, power.expr)};
649}
650
656template <typename Scalar>
657Variable<Scalar> pow(const Variable<Scalar>& base,
658 const ScalarLike auto& power) {
659 return Variable{detail::pow(base.expr, Variable<Scalar>(power).expr)};
660}
661
667template <typename Scalar>
668Variable<Scalar> pow(const Variable<Scalar>& base,
669 const Variable<Scalar>& power) {
670 return Variable{detail::pow(base.expr, power.expr)};
671}
672
677template <typename Scalar>
678Variable<Scalar> sign(const Variable<Scalar>& x) {
679 return Variable{detail::sign(x.expr)};
680}
681
686template <typename Scalar>
687Variable<Scalar> sin(const Variable<Scalar>& x) {
688 return Variable{detail::sin(x.expr)};
689}
690
695template <typename Scalar>
696Variable<Scalar> sinh(const Variable<Scalar>& x) {
697 return Variable{detail::sinh(x.expr)};
698}
699
704template <typename Scalar>
705Variable<Scalar> sqrt(const Variable<Scalar>& x) {
706 return Variable{detail::sqrt(x.expr)};
707}
708
713template <typename Scalar>
714Variable<Scalar> tan(const Variable<Scalar>& x) {
715 return Variable{detail::tan(x.expr)};
716}
717
722template <typename Scalar>
723Variable<Scalar> tanh(const Variable<Scalar>& x) {
724 return Variable{detail::tanh(x.expr)};
725}
726
733template <typename Scalar>
734Variable<Scalar> hypot(const Variable<Scalar>& x, const Variable<Scalar>& y,
735 const Variable<Scalar>& z) {
736 return Variable{detail::hypot(x.expr, y.expr, z.expr)};
737}
738
739// The standard form for equality constraints is c(x) = 0, and the standard form
740// for inequality constraints is c(x) ≥ 0. make_constraints() takes constraints
741// of the form lhs = rhs or lhs ≥ rhs and converts them to lhs - rhs = 0 or
742// lhs - rhs ≥ 0.
743
744template <typename Scalar, ScalarLike LHS, ScalarLike RHS>
745 requires SleipnirScalarLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
746auto make_constraints(LHS&& lhs, RHS&& rhs) {
747 gch::small_vector<Variable<Scalar>> constraints;
748 constraints.emplace_back(lhs - rhs);
749
750 return constraints;
751}
752
753template <typename Scalar, ScalarLike LHS, MatrixLike RHS>
754 requires SleipnirScalarLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
755auto make_constraints(LHS&& lhs, RHS&& rhs) {
756 gch::small_vector<Variable<Scalar>> constraints;
757 constraints.reserve(rhs.rows() * rhs.cols());
758
759 for (int row = 0; row < rhs.rows(); ++row) {
760 for (int col = 0; col < rhs.cols(); ++col) {
761 // Make right-hand side zero
762 constraints.emplace_back(lhs - rhs[row, col]);
763 }
764 }
765
766 return constraints;
767}
768
769template <typename Scalar, MatrixLike LHS, ScalarLike RHS>
770 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
771auto make_constraints(LHS&& lhs, RHS&& rhs) {
772 gch::small_vector<Variable<Scalar>> constraints;
773 constraints.reserve(lhs.rows() * lhs.cols());
774
775 for (int row = 0; row < lhs.rows(); ++row) {
776 for (int col = 0; col < lhs.cols(); ++col) {
777 // Make right-hand side zero
778 constraints.emplace_back(lhs[row, col] - rhs);
779 }
780 }
781
782 return constraints;
783}
784
785template <typename Scalar, MatrixLike LHS, MatrixLike RHS>
786 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
787auto make_constraints(LHS&& lhs, RHS&& rhs) {
788 slp_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
789
790 gch::small_vector<Variable<Scalar>> constraints;
791 constraints.reserve(lhs.rows() * lhs.cols());
792
793 for (int row = 0; row < lhs.rows(); ++row) {
794 for (int col = 0; col < lhs.cols(); ++col) {
795 // Make right-hand side zero
796 constraints.emplace_back(lhs[row, col] - rhs[row, col]);
797 }
798 }
799
800 return constraints;
801}
802
806template <typename Scalar>
809 gch::small_vector<Variable<Scalar>> constraints;
810
816 std::initializer_list<EqualityConstraints> equality_constraints) {
817 for (const auto& elem : equality_constraints) {
818 constraints.insert(constraints.end(), elem.constraints.begin(),
819 elem.constraints.end());
820 }
821 }
822
830 const std::vector<EqualityConstraints>& equality_constraints) {
831 for (const auto& elem : equality_constraints) {
832 constraints.insert(constraints.end(), elem.constraints.begin(),
833 elem.constraints.end());
834 }
835 }
836
844 template <typename LHS, typename RHS>
845 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
850
852 // NOLINTNEXTLINE (google-explicit-constructor)
853 operator bool() {
854 return std::ranges::all_of(constraints, [](auto& constraint) {
855 return constraint.value() == Scalar(0);
856 });
857 }
858};
859
863template <typename Scalar>
866 gch::small_vector<Variable<Scalar>> constraints;
867
873 std::initializer_list<InequalityConstraints> inequality_constraints) {
874 for (const auto& elem : inequality_constraints) {
875 constraints.insert(constraints.end(), elem.constraints.begin(),
876 elem.constraints.end());
877 }
878 }
879
887 const std::vector<InequalityConstraints>& inequality_constraints) {
888 for (const auto& elem : inequality_constraints) {
889 constraints.insert(constraints.end(), elem.constraints.begin(),
890 elem.constraints.end());
891 }
892 }
893
902 template <typename LHS, typename RHS>
903 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
908
910 // NOLINTNEXTLINE (google-explicit-constructor)
911 operator bool() {
912 return std::ranges::all_of(constraints, [](auto& constraint) {
913 return constraint.value() >= Scalar(0);
914 });
915 }
916};
917
922template <typename LHS, typename RHS>
923 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
924 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
925auto operator==(LHS&& lhs, RHS&& rhs) {
926 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
927}
928
933template <typename LHS, typename RHS>
934 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
935 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
936auto operator==(LHS&& lhs, RHS&& rhs) {
937 return EqualityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
938}
939
944template <typename LHS, typename RHS>
945 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
946 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
947auto operator==(LHS&& lhs, RHS&& rhs) {
948 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
949}
950
956template <typename LHS, typename RHS>
957 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
958 (ScalarLike<RHS> || MatrixLike<RHS>) &&
959 (SleipnirType<LHS> || SleipnirType<RHS>)
960auto operator<(LHS&& lhs, RHS&& rhs) {
961 return rhs >= lhs;
962}
963
969template <typename LHS, typename RHS>
970 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
971 (ScalarLike<RHS> || MatrixLike<RHS>) &&
972 (SleipnirType<LHS> || SleipnirType<RHS>)
973auto operator<=(LHS&& lhs, RHS&& rhs) {
974 return rhs >= lhs;
975}
976
982template <typename LHS, typename RHS>
983 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
984 (ScalarLike<RHS> || MatrixLike<RHS>) &&
985 (SleipnirType<LHS> || SleipnirType<RHS>)
986auto operator>(LHS&& lhs, RHS&& rhs) {
987 return lhs >= rhs;
988}
989
995template <typename LHS, typename RHS>
996 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
997 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
998auto operator>=(LHS&& lhs, RHS&& rhs) {
999 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1000}
1001
1007template <typename LHS, typename RHS>
1008 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
1009 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1010auto operator>=(LHS&& lhs, RHS&& rhs) {
1011 return InequalityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
1012}
1013
1019template <typename LHS, typename RHS>
1020 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
1021 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1022auto operator>=(LHS&& lhs, RHS&& rhs) {
1023 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1024}
1025
1031template <typename L, typename X, typename U>
1032 requires(ScalarLike<L> || MatrixLike<L>) && SleipnirType<X> &&
1033 (ScalarLike<U> || MatrixLike<U>)
1034auto bounds(L&& l, X&& x, U&& u) {
1035 return InequalityConstraints{l <= x, x <= u};
1036}
1037
1038} // namespace slp
1039
1040namespace Eigen {
1041
1046template <typename Scalar>
1047struct NumTraits<slp::Variable<Scalar>> : NumTraits<Scalar> {
1056
1058 static constexpr int IsComplex = 0;
1060 static constexpr int IsInteger = 0;
1062 static constexpr int IsSigned = 1;
1064 static constexpr int RequireInitialization = 1;
1066 static constexpr int ReadCost = 1;
1068 static constexpr int AddCost = 3;
1070 static constexpr int MulCost = 3;
1071};
1072
1073} // namespace Eigen
Definition hessian.hpp:35
Definition intrusive_shared_ptr.hpp:27
Definition jacobian.hpp:31
Definition sleipnir_base.hpp:9
Definition variable.hpp:55
ExpressionType type() const
Definition variable.hpp:155
friend Variable< Scalar > operator*(const LHS &lhs, const RHS &rhs)
Definition variable.hpp:163
Variable(const detail::ExpressionPtr< Scalar > &expr)
Definition variable.hpp:102
Variable< Scalar > & operator/=(const Variable< Scalar > &rhs)
Definition variable.hpp:210
Variable< Scalar > & operator*=(const Variable< Scalar > &rhs)
Definition variable.hpp:191
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:220
void set_value(Scalar value)
Definition variable.hpp:125
friend Variable< Scalar > operator/(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:201
Variable(std::floating_point auto value)
Definition variable.hpp:87
constexpr Variable(detail::ExpressionPtr< Scalar > &&expr)
Definition variable.hpp:107
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs)
Definition variable.hpp:263
Variable(Scalar value)
Definition variable.hpp:70
constexpr Variable(std::nullptr_t)
Constructs an empty Variable.
Definition variable.hpp:64
Variable< Scalar > & operator=(ScalarLike auto value)
Definition variable.hpp:114
Variable()=default
Constructs a linear Variable with a value of zero.
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs)
Definition variable.hpp:256
friend Variable< Scalar > operator*(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:182
Variable(std::integral auto value)
Definition variable.hpp:95
Variable(SleipnirMatrixLike< Scalar > auto value)
Definition variable.hpp:79
Variable< Scalar > & operator+=(const Variable< Scalar > &rhs)
Definition variable.hpp:229
Scalar_ Scalar
Scalar type alias.
Definition variable.hpp:58
Scalar value()
Definition variable.hpp:141
Variable< Scalar > & operator-=(const Variable< Scalar > &rhs)
Definition variable.hpp:248
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:239
Definition concepts.hpp:18
Definition concepts.hpp:24
Definition concepts.hpp:33
Definition concepts.hpp:15
Definition variable.hpp:807
EqualityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:848
EqualityConstraints(std::initializer_list< EqualityConstraints > equality_constraints)
Definition variable.hpp:815
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar equality constraints.
Definition variable.hpp:809
EqualityConstraints(const std::vector< EqualityConstraints > &equality_constraints)
Definition variable.hpp:829
Definition variable.hpp:864
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar inequality constraints.
Definition variable.hpp:866
InequalityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:906
InequalityConstraints(const std::vector< InequalityConstraints > &inequality_constraints)
Definition variable.hpp:886
InequalityConstraints(std::initializer_list< InequalityConstraints > inequality_constraints)
Definition variable.hpp:872