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 <initializer_list>
8#include <source_location>
9#include <utility>
10#include <vector>
11
12#include <Eigen/Core>
13#include <gch/small_vector.hpp>
14
15#include "sleipnir/autodiff/expression.hpp"
16#include "sleipnir/autodiff/expression_graph.hpp"
17#include "sleipnir/autodiff/sleipnir_base.hpp"
18#include "sleipnir/util/assert.hpp"
19#include "sleipnir/util/concepts.hpp"
20
21#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
22#include "sleipnir/util/print.hpp"
23#endif
24
25namespace slp {
26
27// Forward declarations for friend declarations in Variable
28
29namespace detail {
30
31template <typename Scalar>
32class AdjointExpressionGraph;
33
34} // namespace detail
35
36template <typename Scalar, int UpLo = Eigen::Lower | Eigen::Upper>
37 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
38class Hessian;
39
40template <typename Scalar>
41class Jacobian;
42
48template <typename Scalar_>
49class Variable : public SleipnirBase {
50 public:
54 using Scalar = Scalar_;
55
59 Variable() = default;
60
64 explicit constexpr Variable(std::nullptr_t) : expr{nullptr} {}
65
71 // NOLINTNEXTLINE (google-explicit-constructor)
73 requires(!MatrixLike<Scalar>)
74 : expr{detail::make_expression_ptr<detail::ConstExpression<Scalar>>(
75 value)} {}
76
82 // NOLINTNEXTLINE (google-explicit-constructor)
84 slp_assert(value.rows() == 1 && value.cols() == 1);
85 }
86
92 // NOLINTNEXTLINE (google-explicit-constructor)
93 Variable(std::floating_point auto value)
94 : expr{detail::make_expression_ptr<detail::ConstExpression<Scalar>>(
95 Scalar(value))} {}
96
102 // NOLINTNEXTLINE (google-explicit-constructor)
103 Variable(std::integral auto value)
104 : expr{detail::make_expression_ptr<detail::ConstExpression<Scalar>>(
105 Scalar(value))} {}
106
112 explicit Variable(const detail::ExpressionPtr<Scalar>& expr) : expr{expr} {}
113
119 explicit constexpr Variable(detail::ExpressionPtr<Scalar>&& expr)
120 : expr{std::move(expr)} {}
121
129 expr = detail::make_expression_ptr<detail::ConstExpression<Scalar>>(value);
130 m_graph_initialized = false;
131
132 return *this;
133 }
134
141#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
142 // We only need to check the first argument since unary and binary operators
143 // both use it
144 if (expr->args[0] != nullptr) {
145 auto location = std::source_location::current();
146 slp::println(
147 stderr,
148 "WARNING: {}:{}: {}: Modified the value of a dependent variable",
149 location.file_name(), location.line(), location.function_name());
150 }
151#endif
152 expr->val = Scalar(value);
153 }
154
161 if (!m_graph_initialized) {
162 m_graph = detail::topological_sort(expr);
163 m_graph_initialized = true;
164 }
165 detail::update_values(m_graph);
166
167 return Scalar(expr->val);
168 }
169
176 ExpressionType type() const { return expr->type(); }
177
185 template <ScalarLike LHS, SleipnirScalarLike<Scalar> RHS>
186 friend Variable<Scalar> operator*(const LHS& lhs, const RHS& rhs) {
187 return Variable{Variable<Scalar>{lhs}.expr * rhs.expr};
188 }
189
197 template <SleipnirScalarLike<Scalar> LHS, ScalarLike RHS>
198 friend Variable<Scalar> operator*(const LHS& lhs, const RHS& rhs) {
199 return Variable{lhs.expr * Variable<Scalar>{rhs}.expr};
200 }
201
210 const Variable<Scalar>& rhs) {
211 return Variable{lhs.expr * rhs.expr};
212 }
213
221 *this = *this * rhs;
222 return *this;
223 }
224
233 const Variable<Scalar>& rhs) {
234 return Variable{lhs.expr / rhs.expr};
235 }
236
244 *this = *this / rhs;
245 return *this;
246 }
247
256 const Variable<Scalar>& rhs) {
257 return Variable{lhs.expr + rhs.expr};
258 }
259
267 *this = *this + rhs;
268 return *this;
269 }
270
279 const Variable<Scalar>& rhs) {
280 return Variable{lhs.expr - rhs.expr};
281 }
282
290 *this = *this - rhs;
291 return *this;
292 }
293
300 return Variable{-lhs.expr};
301 }
302
309 return Variable{+lhs.expr};
310 }
311
312 private:
315 detail::make_expression_ptr<detail::DecisionVariableExpression<Scalar>>();
316
319 gch::small_vector<detail::Expression<Scalar>*> m_graph;
320
322 bool m_graph_initialized = false;
323
324 template <typename Scalar>
325 friend Variable<Scalar> abs(const Variable<Scalar>& x);
326 template <typename Scalar>
327 friend Variable<Scalar> acos(const Variable<Scalar>& x);
328 template <typename Scalar>
329 friend Variable<Scalar> asin(const Variable<Scalar>& x);
330 template <typename Scalar>
331 friend Variable<Scalar> atan(const Variable<Scalar>& x);
332 template <typename Scalar>
333 friend Variable<Scalar> atan2(const ScalarLike auto& y,
334 const Variable<Scalar>& x);
335 template <typename Scalar>
336 friend Variable<Scalar> atan2(const Variable<Scalar>& y,
337 const ScalarLike auto& x);
338 template <typename Scalar>
339 friend Variable<Scalar> atan2(const Variable<Scalar>& y,
340 const Variable<Scalar>& x);
341 template <typename Scalar>
342 friend Variable<Scalar> cbrt(const Variable<Scalar>& x);
343 template <typename Scalar>
344 friend Variable<Scalar> cos(const Variable<Scalar>& x);
345 template <typename Scalar>
346 friend Variable<Scalar> cosh(const Variable<Scalar>& x);
347 template <typename Scalar>
348 friend Variable<Scalar> erf(const Variable<Scalar>& x);
349 template <typename Scalar>
350 friend Variable<Scalar> exp(const Variable<Scalar>& x);
351 template <typename Scalar>
352 friend Variable<Scalar> hypot(const ScalarLike auto& x,
353 const Variable<Scalar>& y);
354 template <typename Scalar>
355 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
356 const ScalarLike auto& y);
357 template <typename Scalar>
358 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
359 const Variable<Scalar>& y);
360 template <typename Scalar>
361 friend Variable<Scalar> log(const Variable<Scalar>& x);
362 template <typename Scalar>
363 friend Variable<Scalar> log10(const Variable<Scalar>& x);
364 template <typename Scalar>
365 friend Variable<Scalar> pow(const ScalarLike auto& base,
366 const Variable<Scalar>& power);
367 template <typename Scalar>
368 friend Variable<Scalar> pow(const Variable<Scalar>& base,
369 const ScalarLike auto& power);
370 template <typename Scalar>
371 friend Variable<Scalar> pow(const Variable<Scalar>& base,
372 const Variable<Scalar>& power);
373 template <typename Scalar>
374 friend Variable<Scalar> sign(const Variable<Scalar>& x);
375 template <typename Scalar>
376 friend Variable<Scalar> sin(const Variable<Scalar>& x);
377 template <typename Scalar>
378 friend Variable<Scalar> sinh(const Variable<Scalar>& x);
379 template <typename Scalar>
380 friend Variable<Scalar> sqrt(const Variable<Scalar>& x);
381 template <typename Scalar>
382 friend Variable<Scalar> tan(const Variable<Scalar>& x);
383 template <typename Scalar>
384 friend Variable<Scalar> tanh(const Variable<Scalar>& x);
385 template <typename Scalar>
386 friend Variable<Scalar> hypot(const Variable<Scalar>& x,
387 const Variable<Scalar>& y,
388 const Variable<Scalar>& z);
389
391 template <typename Scalar, int UpLo>
392 requires(UpLo == Eigen::Lower) || (UpLo == (Eigen::Lower | Eigen::Upper))
393 friend class Hessian;
394 template <typename Scalar>
395 friend class Jacobian;
396};
397
398template <template <typename> typename T, typename Scalar>
399 requires SleipnirMatrixLike<T<Scalar>, Scalar>
400Variable(T<Scalar>) -> Variable<Scalar>;
401
402template <std::floating_point T>
403Variable(T) -> Variable<T>;
404
405template <std::integral T>
406Variable(T) -> Variable<T>;
407
414template <typename Scalar>
415Variable<Scalar> abs(const Variable<Scalar>& x) {
416 return Variable{detail::abs(x.expr)};
417}
418
425template <typename Scalar>
426Variable<Scalar> acos(const Variable<Scalar>& x) {
427 return Variable{detail::acos(x.expr)};
428}
429
436template <typename Scalar>
437Variable<Scalar> asin(const Variable<Scalar>& x) {
438 return Variable{detail::asin(x.expr)};
439}
440
447template <typename Scalar>
448Variable<Scalar> atan(const Variable<Scalar>& x) {
449 return Variable{detail::atan(x.expr)};
450}
451
459template <typename Scalar>
460Variable<Scalar> atan2(const ScalarLike auto& y, const Variable<Scalar>& x) {
461 return Variable{detail::atan2(Variable<Scalar>(y).expr, x.expr)};
462}
463
471template <typename Scalar>
472Variable<Scalar> atan2(const Variable<Scalar>& y, const ScalarLike auto& x) {
473 return Variable{detail::atan2(y.expr, Variable<Scalar>(x).expr)};
474}
475
483template <typename Scalar>
484Variable<Scalar> atan2(const Variable<Scalar>& y, const Variable<Scalar>& x) {
485 return Variable{detail::atan2(y.expr, x.expr)};
486}
487
494template <typename Scalar>
495Variable<Scalar> cbrt(const Variable<Scalar>& x) {
496 return Variable{detail::cbrt(x.expr)};
497}
498
505template <typename Scalar>
506Variable<Scalar> cos(const Variable<Scalar>& x) {
507 return Variable{detail::cos(x.expr)};
508}
509
516template <typename Scalar>
517Variable<Scalar> cosh(const Variable<Scalar>& x) {
518 return Variable{detail::cosh(x.expr)};
519}
520
527template <typename Scalar>
528Variable<Scalar> erf(const Variable<Scalar>& x) {
529 return Variable{detail::erf(x.expr)};
530}
531
538template <typename Scalar>
539Variable<Scalar> exp(const Variable<Scalar>& x) {
540 return Variable{detail::exp(x.expr)};
541}
542
550template <typename Scalar>
551Variable<Scalar> hypot(const ScalarLike auto& x, const Variable<Scalar>& y) {
552 return Variable{detail::hypot(Variable<Scalar>(x).expr, y.expr)};
553}
554
562template <typename Scalar>
563Variable<Scalar> hypot(const Variable<Scalar>& x, const ScalarLike auto& y) {
564 return Variable{detail::hypot(x.expr, Variable<Scalar>(y).expr)};
565}
566
574template <typename Scalar>
575Variable<Scalar> hypot(const Variable<Scalar>& x, const Variable<Scalar>& y) {
576 return Variable{detail::hypot(x.expr, y.expr)};
577}
578
585template <typename Scalar>
586Variable<Scalar> log(const Variable<Scalar>& x) {
587 return Variable{detail::log(x.expr)};
588}
589
596template <typename Scalar>
597Variable<Scalar> log10(const Variable<Scalar>& x) {
598 return Variable{detail::log10(x.expr)};
599}
600
608template <typename Scalar>
609Variable<Scalar> pow(const ScalarLike auto& base,
610 const Variable<Scalar>& power) {
611 return Variable{detail::pow(Variable<Scalar>(base).expr, power.expr)};
612}
613
621template <typename Scalar>
622Variable<Scalar> pow(const Variable<Scalar>& base,
623 const ScalarLike auto& power) {
624 return Variable{detail::pow(base.expr, Variable<Scalar>(power).expr)};
625}
626
634template <typename Scalar>
635Variable<Scalar> pow(const Variable<Scalar>& base,
636 const Variable<Scalar>& power) {
637 return Variable{detail::pow(base.expr, power.expr)};
638}
639
646template <typename Scalar>
647Variable<Scalar> sign(const Variable<Scalar>& x) {
648 return Variable{detail::sign(x.expr)};
649}
650
657template <typename Scalar>
658Variable<Scalar> sin(const Variable<Scalar>& x) {
659 return Variable{detail::sin(x.expr)};
660}
661
668template <typename Scalar>
669Variable<Scalar> sinh(const Variable<Scalar>& x) {
670 return Variable{detail::sinh(x.expr)};
671}
672
679template <typename Scalar>
680Variable<Scalar> sqrt(const Variable<Scalar>& x) {
681 return Variable{detail::sqrt(x.expr)};
682}
683
690template <typename Scalar>
691Variable<Scalar> tan(const Variable<Scalar>& x) {
692 return Variable{detail::tan(x.expr)};
693}
694
701template <typename Scalar>
702Variable<Scalar> tanh(const Variable<Scalar>& x) {
703 return Variable{detail::tanh(x.expr)};
704}
705
714template <typename Scalar>
715Variable<Scalar> hypot(const Variable<Scalar>& x, const Variable<Scalar>& y,
716 const Variable<Scalar>& z) {
717 return Variable{slp::sqrt(slp::pow(x, 2) + slp::pow(y, 2) + slp::pow(z, 2))};
718}
719
720// The standard form for equality constraints is c(x) = 0, and the standard form
721// for inequality constraints is c(x) ≥ 0. make_constraints() takes constraints
722// of the form lhs = rhs or lhs ≥ rhs and converts them to lhs - rhs = 0 or
723// lhs - rhs ≥ 0.
724
725template <typename Scalar, ScalarLike LHS, ScalarLike RHS>
726 requires SleipnirScalarLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
727auto make_constraints(LHS&& lhs, RHS&& rhs) {
728 gch::small_vector<Variable<Scalar>> constraints;
729 constraints.emplace_back(lhs - rhs);
730
731 return constraints;
732}
733
734template <typename Scalar, ScalarLike LHS, MatrixLike RHS>
735 requires SleipnirScalarLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
736auto make_constraints(LHS&& lhs, RHS&& rhs) {
737 gch::small_vector<Variable<Scalar>> constraints;
738 constraints.reserve(rhs.rows() * rhs.cols());
739
740 for (int row = 0; row < rhs.rows(); ++row) {
741 for (int col = 0; col < rhs.cols(); ++col) {
742 // Make right-hand side zero
743 if constexpr (EigenMatrixLike<decltype(rhs)>) {
744 constraints.emplace_back(lhs - rhs(row, col));
745 } else {
746 constraints.emplace_back(lhs - rhs[row, col]);
747 }
748 }
749 }
750
751 return constraints;
752}
753
754template <typename Scalar, MatrixLike LHS, ScalarLike RHS>
755 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirScalarLike<RHS, Scalar>
756auto make_constraints(LHS&& lhs, RHS&& rhs) {
757 gch::small_vector<Variable<Scalar>> constraints;
758 constraints.reserve(lhs.rows() * lhs.cols());
759
760 for (int row = 0; row < lhs.rows(); ++row) {
761 for (int col = 0; col < lhs.cols(); ++col) {
762 // Make right-hand side zero
763 if constexpr (EigenMatrixLike<decltype(lhs)>) {
764 constraints.emplace_back(lhs(row, col) - rhs);
765 } else {
766 constraints.emplace_back(lhs[row, col] - rhs);
767 }
768 }
769 }
770
771 return constraints;
772}
773
774template <typename Scalar, MatrixLike LHS, MatrixLike RHS>
775 requires SleipnirMatrixLike<LHS, Scalar> || SleipnirMatrixLike<RHS, Scalar>
776auto make_constraints(LHS&& lhs, RHS&& rhs) {
777 slp_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
778
779 gch::small_vector<Variable<Scalar>> constraints;
780 constraints.reserve(lhs.rows() * lhs.cols());
781
782 for (int row = 0; row < lhs.rows(); ++row) {
783 for (int col = 0; col < lhs.cols(); ++col) {
784 // Make right-hand side zero
785 if constexpr (EigenMatrixLike<LHS> && EigenMatrixLike<RHS>) {
786 constraints.emplace_back(lhs(row, col) - rhs(row, col));
787 } else if constexpr (EigenMatrixLike<LHS> &&
788 SleipnirMatrixLike<RHS, Scalar>) {
789 constraints.emplace_back(lhs(row, col) - rhs[row, col]);
790 } else if constexpr (SleipnirMatrixLike<LHS, Scalar> &&
791 EigenMatrixLike<RHS>) {
792 constraints.emplace_back(lhs[row, col] - rhs(row, col));
793 } else if constexpr (SleipnirMatrixLike<LHS, Scalar> &&
794 SleipnirMatrixLike<RHS, Scalar>) {
795 constraints.emplace_back(lhs[row, col] - rhs[row, col]);
796 }
797 }
798 }
799
800 return constraints;
801}
802
808template <typename Scalar>
811 gch::small_vector<Variable<Scalar>> constraints;
812
819 std::initializer_list<EqualityConstraints> equality_constraints) {
820 for (const auto& elem : equality_constraints) {
821 constraints.insert(constraints.end(), elem.constraints.begin(),
822 elem.constraints.end());
823 }
824 }
825
834 const std::vector<EqualityConstraints>& equality_constraints) {
835 for (const auto& elem : equality_constraints) {
836 constraints.insert(constraints.end(), elem.constraints.begin(),
837 elem.constraints.end());
838 }
839 }
840
850 template <typename LHS, typename RHS>
851 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
856
860 // NOLINTNEXTLINE (google-explicit-constructor)
861 operator bool() {
862 return std::ranges::all_of(constraints, [](auto& constraint) {
863 return constraint.value() == Scalar(0);
864 });
865 }
866};
867
873template <typename Scalar>
876 gch::small_vector<Variable<Scalar>> constraints;
877
885 std::initializer_list<InequalityConstraints> inequality_constraints) {
886 for (const auto& elem : inequality_constraints) {
887 constraints.insert(constraints.end(), elem.constraints.begin(),
888 elem.constraints.end());
889 }
890 }
891
901 const std::vector<InequalityConstraints>& inequality_constraints) {
902 for (const auto& elem : inequality_constraints) {
903 constraints.insert(constraints.end(), elem.constraints.begin(),
904 elem.constraints.end());
905 }
906 }
907
917 template <typename LHS, typename RHS>
918 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
923
927 // NOLINTNEXTLINE (google-explicit-constructor)
928 operator bool() {
929 return std::ranges::all_of(constraints, [](auto& constraint) {
930 return constraint.value() >= Scalar(0);
931 });
932 }
933};
934
941template <typename LHS, typename RHS>
942 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
943 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
944auto operator==(LHS&& lhs, RHS&& rhs) {
945 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
946}
947
954template <typename LHS, typename RHS>
955 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
956 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
957auto operator==(LHS&& lhs, RHS&& rhs) {
958 return EqualityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
959}
960
967template <typename LHS, typename RHS>
968 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
969 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
970auto operator==(LHS&& lhs, RHS&& rhs) {
971 return EqualityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
972}
973
981template <typename LHS, typename RHS>
982 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
983 (ScalarLike<RHS> || MatrixLike<RHS>) &&
984 (SleipnirType<LHS> || SleipnirType<RHS>)
985auto operator<(LHS&& lhs, RHS&& rhs) {
986 return rhs >= lhs;
987}
988
996template <typename LHS, typename RHS>
997 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
998 (ScalarLike<RHS> || MatrixLike<RHS>) &&
999 (SleipnirType<LHS> || SleipnirType<RHS>)
1000auto operator<=(LHS&& lhs, RHS&& rhs) {
1001 return rhs >= lhs;
1002}
1003
1011template <typename LHS, typename RHS>
1012 requires(ScalarLike<LHS> || MatrixLike<LHS>) &&
1013 (ScalarLike<RHS> || MatrixLike<RHS>) &&
1014 (SleipnirType<LHS> || SleipnirType<RHS>)
1015auto operator>(LHS&& lhs, RHS&& rhs) {
1016 return lhs >= rhs;
1017}
1018
1026template <typename LHS, typename RHS>
1027 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
1028 (ScalarLike<RHS> || MatrixLike<RHS>) && (!SleipnirType<RHS>)
1029auto operator>=(LHS&& lhs, RHS&& rhs) {
1030 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1031}
1032
1040template <typename LHS, typename RHS>
1041 requires(ScalarLike<LHS> || MatrixLike<LHS>) && (!SleipnirType<LHS>) &&
1042 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1043auto operator>=(LHS&& lhs, RHS&& rhs) {
1044 return InequalityConstraints<typename std::decay_t<RHS>::Scalar>{lhs, rhs};
1045}
1046
1054template <typename LHS, typename RHS>
1055 requires(ScalarLike<LHS> || MatrixLike<LHS>) && SleipnirType<LHS> &&
1056 (ScalarLike<RHS> || MatrixLike<RHS>) && SleipnirType<RHS>
1057auto operator>=(LHS&& lhs, RHS&& rhs) {
1058 return InequalityConstraints<typename std::decay_t<LHS>::Scalar>{lhs, rhs};
1059}
1060
1061} // namespace slp
1062
1063namespace Eigen {
1064
1070template <typename Scalar>
1071struct NumTraits<slp::Variable<Scalar>> : NumTraits<Scalar> {
1078
1080 static constexpr int IsComplex = 0;
1082 static constexpr int IsInteger = 0;
1084 static constexpr int IsSigned = 1;
1086 static constexpr int RequireInitialization = 1;
1088 static constexpr int ReadCost = 1;
1090 static constexpr int AddCost = 3;
1092 static constexpr int MulCost = 3;
1093};
1094
1095} // namespace Eigen
Definition hessian.hpp:30
Definition intrusive_shared_ptr.hpp:29
Definition jacobian.hpp:30
Definition sleipnir_base.hpp:11
Definition variable.hpp:49
ExpressionType type() const
Definition variable.hpp:176
friend Variable< Scalar > operator*(const LHS &lhs, const RHS &rhs)
Definition variable.hpp:186
Variable(const detail::ExpressionPtr< Scalar > &expr)
Definition variable.hpp:112
Variable< Scalar > & operator/=(const Variable< Scalar > &rhs)
Definition variable.hpp:243
Variable< Scalar > & operator*=(const Variable< Scalar > &rhs)
Definition variable.hpp:220
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:255
void set_value(Scalar value)
Definition variable.hpp:140
friend Variable< Scalar > operator/(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:232
Variable(std::floating_point auto value)
Definition variable.hpp:93
constexpr Variable(detail::ExpressionPtr< Scalar > &&expr)
Definition variable.hpp:119
friend Variable< Scalar > operator+(const Variable< Scalar > &lhs)
Definition variable.hpp:308
Variable(Scalar value)
Definition variable.hpp:72
constexpr Variable(std::nullptr_t)
Definition variable.hpp:64
Variable< Scalar > & operator=(ScalarLike auto value)
Definition variable.hpp:128
Variable()=default
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs)
Definition variable.hpp:299
friend Variable< Scalar > operator*(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:209
Variable(std::integral auto value)
Definition variable.hpp:103
Variable(SleipnirMatrixLike< Scalar > auto value)
Definition variable.hpp:83
Variable< Scalar > & operator+=(const Variable< Scalar > &rhs)
Definition variable.hpp:266
Scalar_ Scalar
Definition variable.hpp:54
Scalar value()
Definition variable.hpp:160
Variable< Scalar > & operator-=(const Variable< Scalar > &rhs)
Definition variable.hpp:289
friend Variable< Scalar > operator-(const Variable< Scalar > &lhs, const Variable< Scalar > &rhs)
Definition variable.hpp:278
Definition adjoint_expression_graph.hpp:26
Definition concepts.hpp:18
Definition concepts.hpp:24
Definition concepts.hpp:33
Definition concepts.hpp:15
Definition variable.hpp:809
EqualityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:854
EqualityConstraints(std::initializer_list< EqualityConstraints > equality_constraints)
Definition variable.hpp:818
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar equality constraints.
Definition variable.hpp:811
EqualityConstraints(const std::vector< EqualityConstraints > &equality_constraints)
Definition variable.hpp:833
Definition variable.hpp:874
gch::small_vector< Variable< Scalar > > constraints
A vector of scalar inequality constraints.
Definition variable.hpp:876
InequalityConstraints(LHS &&lhs, RHS &&rhs)
Definition variable.hpp:921
InequalityConstraints(const std::vector< InequalityConstraints > &inequality_constraints)
Definition variable.hpp:900
InequalityConstraints(std::initializer_list< InequalityConstraints > inequality_constraints)
Definition variable.hpp:884