Sleipnir C++ API
Loading...
Searching...
No Matches
Variable.hpp
Go to the documentation of this file.
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <algorithm>
6#include <concepts>
7#include <initializer_list>
8#include <type_traits>
9#include <utility>
10#include <vector>
11
12#include <Eigen/Core>
13
20
21namespace sleipnir {
22
23// Forward declarations for friend declarations in Variable
24namespace detail {
25class ExpressionGraph;
26} // namespace detail
29
34 public:
38 Variable() = default;
39
43 explicit constexpr Variable(std::nullptr_t) : expr{nullptr} {}
44
50 Variable(std::floating_point auto value) // NOLINT
51 : expr{detail::MakeExpressionPtr<detail::ConstExpression>(value)} {}
52
58 Variable(std::integral auto value) // NOLINT
59 : expr{detail::MakeExpressionPtr<detail::ConstExpression>(value)} {}
60
66 explicit Variable(const detail::ExpressionPtr& expr) : expr{expr} {}
67
73 explicit constexpr Variable(detail::ExpressionPtr&& expr)
74 : expr{std::move(expr)} {}
75
81 Variable& operator=(double value) {
82 expr = detail::MakeExpressionPtr<detail::ConstExpression>(value);
83
84 return *this;
85 }
86
92 void SetValue(double value) {
93 if (expr->IsConstant(0.0)) {
94 expr = detail::MakeExpressionPtr<detail::ConstExpression>(value);
95 } else {
96 // We only need to check the first argument since unary and binary
97 // operators both use it
98 if (expr->args[0] != nullptr && !expr->args[0]->IsConstant(0.0)) {
100 stderr,
101 "WARNING: {}:{}: Modified the value of a dependent variable",
102 __FILE__, __LINE__);
103 }
104 expr->value = value;
105 }
106 }
107
115 const Variable& rhs) {
116 return Variable{lhs.expr * rhs.expr};
117 }
118
125 *this = *this * rhs;
126 return *this;
127 }
128
136 const Variable& rhs) {
137 return Variable{lhs.expr / rhs.expr};
138 }
139
146 *this = *this / rhs;
147 return *this;
148 }
149
157 const Variable& rhs) {
158 return Variable{lhs.expr + rhs.expr};
159 }
160
167 *this = *this + rhs;
168 return *this;
169 }
170
178 const Variable& rhs) {
179 return Variable{lhs.expr - rhs.expr};
180 }
181
188 *this = *this - rhs;
189 return *this;
190 }
191
198 return Variable{-lhs.expr};
199 }
200
207 return Variable{+lhs.expr};
208 }
209
213 double Value();
214
219 ExpressionType Type() const { return expr->Type(); }
220
221 private:
224 detail::MakeExpressionPtr<detail::DecisionVariableExpression>();
225
226 friend SLEIPNIR_DLLEXPORT Variable abs(const Variable& x);
227 friend SLEIPNIR_DLLEXPORT Variable acos(const Variable& x);
228 friend SLEIPNIR_DLLEXPORT Variable asin(const Variable& x);
229 friend SLEIPNIR_DLLEXPORT Variable atan(const Variable& x);
230 friend SLEIPNIR_DLLEXPORT Variable atan2(const Variable& y,
231 const Variable& x);
232 friend SLEIPNIR_DLLEXPORT Variable cos(const Variable& x);
233 friend SLEIPNIR_DLLEXPORT Variable cosh(const Variable& x);
234 friend SLEIPNIR_DLLEXPORT Variable erf(const Variable& x);
235 friend SLEIPNIR_DLLEXPORT Variable exp(const Variable& x);
236 friend SLEIPNIR_DLLEXPORT Variable hypot(const Variable& x,
237 const Variable& y);
238 friend SLEIPNIR_DLLEXPORT Variable log(const Variable& x);
239 friend SLEIPNIR_DLLEXPORT Variable log10(const Variable& x);
240 friend SLEIPNIR_DLLEXPORT Variable pow(const Variable& base,
241 const Variable& power);
242 friend SLEIPNIR_DLLEXPORT Variable sign(const Variable& x);
243 friend SLEIPNIR_DLLEXPORT Variable sin(const Variable& x);
244 friend SLEIPNIR_DLLEXPORT Variable sinh(const Variable& x);
245 friend SLEIPNIR_DLLEXPORT Variable sqrt(const Variable& x);
246 friend SLEIPNIR_DLLEXPORT Variable tan(const Variable& x);
247 friend SLEIPNIR_DLLEXPORT Variable tanh(const Variable& x);
248 friend SLEIPNIR_DLLEXPORT Variable hypot(const Variable& x, const Variable& y,
249 const Variable& z);
250
254};
255
262 return Variable{detail::abs(x.expr)};
263}
264
271 return Variable{detail::acos(x.expr)};
272}
273
280 return Variable{detail::asin(x.expr)};
281}
282
289 return Variable{detail::atan(x.expr)};
290}
291
299 return Variable{detail::atan2(y.expr, x.expr)};
300}
301
308 return Variable{detail::cos(x.expr)};
309}
310
317 return Variable{detail::cosh(x.expr)};
318}
319
326 return Variable{detail::erf(x.expr)};
327}
328
335 return Variable{detail::exp(x.expr)};
336}
337
345 return Variable{detail::hypot(x.expr, y.expr)};
346}
347
355 const Variable& power) {
356 return Variable{detail::pow(base.expr, power.expr)};
357}
358
365 return Variable{detail::log(x.expr)};
366}
367
374 return Variable{detail::log10(x.expr)};
375}
376
383 return Variable{detail::sign(x.expr)};
384}
385
392 return Variable{detail::sin(x.expr)};
393}
394
401 return Variable{detail::sinh(x.expr)};
402}
403
410 return Variable{detail::sqrt(x.expr)};
411}
412
419 return Variable{detail::tan(x.expr)};
420}
421
428 return Variable{detail::tanh(x.expr)};
429}
430
439 const Variable& z) {
441 sleipnir::pow(z, 2))};
442}
443
455template <typename LHS, typename RHS>
457 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
458 (!std::same_as<std::decay_t<LHS>, double> ||
459 !std::same_as<std::decay_t<RHS>, double>)
461 small_vector<Variable> constraints;
462
463 if constexpr (ScalarLike<std::decay_t<LHS>> &&
465 constraints.emplace_back(lhs - rhs);
466 } else if constexpr (ScalarLike<std::decay_t<LHS>> &&
468 int rows;
469 int cols;
470 if constexpr (EigenMatrixLike<std::decay_t<RHS>>) {
471 rows = rhs.rows();
472 cols = rhs.cols();
473 } else {
474 rows = rhs.Rows();
475 cols = rhs.Cols();
476 }
477
478 constraints.reserve(rows * cols);
479
480 for (int row = 0; row < rows; ++row) {
481 for (int col = 0; col < cols; ++col) {
482 // Make right-hand side zero
483 constraints.emplace_back(lhs - rhs(row, col));
484 }
485 }
486 } else if constexpr (MatrixLike<std::decay_t<LHS>> &&
488 int rows;
489 int cols;
490 if constexpr (EigenMatrixLike<std::decay_t<LHS>>) {
491 rows = lhs.rows();
492 cols = lhs.cols();
493 } else {
494 rows = lhs.Rows();
495 cols = lhs.Cols();
496 }
497
498 constraints.reserve(rows * cols);
499
500 for (int row = 0; row < rows; ++row) {
501 for (int col = 0; col < cols; ++col) {
502 // Make right-hand side zero
503 constraints.emplace_back(lhs(row, col) - rhs);
504 }
505 }
506 } else if constexpr (MatrixLike<std::decay_t<LHS>> &&
508 int lhsRows;
509 int lhsCols;
510 if constexpr (EigenMatrixLike<std::decay_t<LHS>>) {
511 lhsRows = lhs.rows();
512 lhsCols = lhs.cols();
513 } else {
514 lhsRows = lhs.Rows();
515 lhsCols = lhs.Cols();
516 }
517
518 [[maybe_unused]]
519 int rhsRows;
520 [[maybe_unused]]
521 int rhsCols;
522 if constexpr (EigenMatrixLike<std::decay_t<RHS>>) {
523 rhsRows = rhs.rows();
524 rhsCols = rhs.cols();
525 } else {
526 rhsRows = rhs.Rows();
527 rhsCols = rhs.Cols();
528 }
529
531 constraints.reserve(lhsRows * lhsCols);
532
533 for (int row = 0; row < lhsRows; ++row) {
534 for (int col = 0; col < lhsCols; ++col) {
535 // Make right-hand side zero
536 constraints.emplace_back(lhs(row, col) - rhs(row, col));
537 }
538 }
539 }
540
541 return constraints;
542}
543
550
557 std::initializer_list<EqualityConstraints> equalityConstraints) {
558 for (const auto& elem : equalityConstraints) {
559 constraints.insert(constraints.end(), elem.constraints.begin(),
560 elem.constraints.end());
561 }
562 }
563
572 const std::vector<EqualityConstraints>& equalityConstraints) {
573 for (const auto& elem : equalityConstraints) {
574 constraints.insert(constraints.end(), elem.constraints.begin(),
575 elem.constraints.end());
576 }
577 }
578
588 template <typename LHS, typename RHS>
590 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
591 (!std::same_as<std::decay_t<LHS>, double> ||
592 !std::same_as<std::decay_t<RHS>, double>)
593 EqualityConstraints(LHS&& lhs, RHS&& rhs)
594 : constraints{MakeConstraints(lhs, rhs)} {}
595
599 operator bool() { // NOLINT
600 return std::all_of(
601 constraints.begin(), constraints.end(),
602 [](auto& constraint) { return constraint.Value() == 0.0; });
603 }
604};
605
612
620 std::initializer_list<InequalityConstraints> inequalityConstraints) {
621 for (const auto& elem : inequalityConstraints) {
622 constraints.insert(constraints.end(), elem.constraints.begin(),
623 elem.constraints.end());
624 }
625 }
626
636 const std::vector<InequalityConstraints>& inequalityConstraints) {
637 for (const auto& elem : inequalityConstraints) {
638 constraints.insert(constraints.end(), elem.constraints.begin(),
639 elem.constraints.end());
640 }
641 }
642
652 template <typename LHS, typename RHS>
654 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
655 (!std::same_as<std::decay_t<LHS>, double> ||
656 !std::same_as<std::decay_t<RHS>, double>)
657 InequalityConstraints(LHS&& lhs, RHS&& rhs)
658 : constraints{MakeConstraints(lhs, rhs)} {}
659
663 operator bool() { // NOLINT
664 return std::all_of(
665 constraints.begin(), constraints.end(),
666 [](auto& constraint) { return constraint.Value() >= 0.0; });
667 }
668};
669
676template <typename LHS, typename RHS>
678 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
679 (!std::same_as<std::decay_t<LHS>, double> ||
680 !std::same_as<std::decay_t<RHS>, double>)
682 return EqualityConstraints{lhs, rhs};
683}
684
692template <typename LHS, typename RHS>
694 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
695 (!std::same_as<std::decay_t<LHS>, double> ||
696 !std::same_as<std::decay_t<RHS>, double>)
698 return rhs >= lhs;
699}
700
708template <typename LHS, typename RHS>
710 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
711 (!std::same_as<std::decay_t<LHS>, double> ||
712 !std::same_as<std::decay_t<RHS>, double>)
714 return rhs >= lhs;
715}
716
724template <typename LHS, typename RHS>
726 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
727 (!std::same_as<std::decay_t<LHS>, double> ||
728 !std::same_as<std::decay_t<RHS>, double>)
730 return lhs >= rhs;
731}
732
740template <typename LHS, typename RHS>
742 (ScalarLike<std::decay_t<RHS>> || MatrixLike<std::decay_t<RHS>>) &&
743 (!std::same_as<std::decay_t<LHS>, double> ||
744 !std::same_as<std::decay_t<RHS>, double>)
747}
748
749} // namespace sleipnir
750
751namespace Eigen {
752
756template <>
757struct NumTraits<sleipnir::Variable> : NumTraits<double> {
761
762 enum {
763 IsComplex = 0,
764 IsInteger = 0,
765 IsSigned = 1,
766 RequireInitialization = 1,
767 ReadCost = 1,
768 AddCost = 3,
769 MulCost = 3
770 };
771};
772
773} // namespace Eigen
#define Assert(condition)
Definition Assert.hpp:24
#define SLEIPNIR_DLLEXPORT
Definition SymbolExports.hpp:34
Definition Hessian.hpp:24
Definition Jacobian.hpp:25
Definition Variable.hpp:33
friend SLEIPNIR_DLLEXPORT Variable operator+(const Variable &lhs)
Definition Variable.hpp:206
friend SLEIPNIR_DLLEXPORT Variable operator*(const Variable &lhs, const Variable &rhs)
Definition Variable.hpp:114
Variable & operator*=(const Variable &rhs)
Definition Variable.hpp:124
friend SLEIPNIR_DLLEXPORT Variable operator-(const Variable &lhs)
Definition Variable.hpp:197
friend SLEIPNIR_DLLEXPORT Variable operator+(const Variable &lhs, const Variable &rhs)
Definition Variable.hpp:156
friend SLEIPNIR_DLLEXPORT Variable operator-(const Variable &lhs, const Variable &rhs)
Definition Variable.hpp:177
ExpressionType Type() const
Definition Variable.hpp:219
Variable(std::floating_point auto value)
Definition Variable.hpp:50
Variable & operator=(double value)
Definition Variable.hpp:81
constexpr Variable(std::nullptr_t)
Definition Variable.hpp:43
Variable & operator-=(const Variable &rhs)
Definition Variable.hpp:187
Variable(const detail::ExpressionPtr &expr)
Definition Variable.hpp:66
friend SLEIPNIR_DLLEXPORT Variable operator/(const Variable &lhs, const Variable &rhs)
Definition Variable.hpp:135
Variable(std::integral auto value)
Definition Variable.hpp:58
Variable & operator+=(const Variable &rhs)
Definition Variable.hpp:166
Variable & operator/=(const Variable &rhs)
Definition Variable.hpp:145
void SetValue(double value)
Definition Variable.hpp:92
constexpr Variable(detail::ExpressionPtr &&expr)
Definition Variable.hpp:73
Definition ExpressionGraph.hpp:19
Definition small_vector.hpp:3616
constexpr iterator insert(const_iterator pos, const_reference value) &&CopyAssignable
Definition small_vector.hpp:3981
constexpr void reserve(size_type new_capacity)
Definition small_vector.hpp:4082
::value &&MoveInsertable constexpr reference emplace_back(Args &&... args)
Definition small_vector.hpp:4071
constexpr iterator end() noexcept
Definition small_vector.hpp:3898
constexpr iterator begin() noexcept
Definition small_vector.hpp:3890
Definition Concepts.hpp:25
Definition Concepts.hpp:28
Definition Concepts.hpp:12
Definition Variable.hpp:751
ExpressionPtr abs(const ExpressionPtr &x)
Definition Expression.hpp:736
ExpressionPtr log(const ExpressionPtr &x)
Definition Expression.hpp:1238
ExpressionPtr exp(const ExpressionPtr &x)
Definition Expression.hpp:1129
ExpressionPtr tanh(const ExpressionPtr &x)
Definition Expression.hpp:1683
ExpressionPtr atan(const ExpressionPtr &x)
Definition Expression.hpp:879
ExpressionPtr sinh(const ExpressionPtr &x)
Definition Expression.hpp:1538
ExpressionPtr log10(const ExpressionPtr &x)
Definition Expression.hpp:1286
ExpressionPtr pow(const ExpressionPtr &base, const ExpressionPtr &power)
Definition Expression.hpp:1370
ExpressionPtr sign(const ExpressionPtr &x)
Definition Expression.hpp:1443
ExpressionPtr atan2(const ExpressionPtr &y, const ExpressionPtr &x)
Definition Expression.hpp:939
ExpressionPtr asin(const ExpressionPtr &x)
Definition Expression.hpp:832
ExpressionPtr erf(const ExpressionPtr &x)
Definition Expression.hpp:1082
ExpressionPtr sin(const ExpressionPtr &x)
Definition Expression.hpp:1491
ExpressionPtr tan(const ExpressionPtr &x)
Definition Expression.hpp:1635
ExpressionPtr acos(const ExpressionPtr &x)
Definition Expression.hpp:785
ExpressionPtr cosh(const ExpressionPtr &x)
Definition Expression.hpp:1034
ExpressionPtr cos(const ExpressionPtr &x)
Definition Expression.hpp:988
ExpressionPtr sqrt(const ExpressionPtr &x)
Definition Expression.hpp:1586
ExpressionPtr hypot(const ExpressionPtr &x, const ExpressionPtr &y)
Definition Expression.hpp:1190
Definition Expression.hpp:18
IntrusiveSharedPtr< T > AllocateIntrusiveShared(Alloc alloc, Args &&... args)
Definition IntrusiveSharedPtr.hpp:275
SLEIPNIR_DLLEXPORT Variable sin(const Variable &x)
Definition Variable.hpp:391
SLEIPNIR_DLLEXPORT Variable tanh(const Variable &x)
Definition Variable.hpp:427
SLEIPNIR_DLLEXPORT Variable asin(const Variable &x)
Definition Variable.hpp:279
SLEIPNIR_DLLEXPORT Variable cosh(const Variable &x)
Definition Variable.hpp:316
SLEIPNIR_DLLEXPORT Variable sign(const Variable &x)
Definition Variable.hpp:382
ExpressionType
Definition ExpressionType.hpp:14
SLEIPNIR_DLLEXPORT Variable atan2(const Variable &y, const Variable &x)
Definition Variable.hpp:298
SLEIPNIR_DLLEXPORT Variable erf(const Variable &x)
Definition Variable.hpp:325
SLEIPNIR_DLLEXPORT Variable sinh(const Variable &x)
Definition Variable.hpp:400
void println(std::format_string< T... > fmt, T &&... args)
Definition Print.hpp:38
SLEIPNIR_DLLEXPORT Variable abs(const Variable &x)
Definition Variable.hpp:261
small_vector< Variable > MakeConstraints(LHS &&lhs, RHS &&rhs)
Definition Variable.hpp:460
SLEIPNIR_DLLEXPORT Variable log(const Variable &x)
Definition Variable.hpp:364
SLEIPNIR_DLLEXPORT Variable pow(const Variable &base, const Variable &power)
Definition Variable.hpp:354
SLEIPNIR_DLLEXPORT Variable hypot(const Variable &x, const Variable &y)
Definition Variable.hpp:344
SLEIPNIR_DLLEXPORT Variable atan(const Variable &x)
Definition Variable.hpp:288
SLEIPNIR_DLLEXPORT Variable cos(const Variable &x)
Definition Variable.hpp:307
SLEIPNIR_DLLEXPORT Variable tan(const Variable &x)
Definition Variable.hpp:418
SLEIPNIR_DLLEXPORT Variable sqrt(const Variable &x)
Definition Variable.hpp:409
SLEIPNIR_DLLEXPORT Variable exp(const Variable &x)
Definition Variable.hpp:334
SLEIPNIR_DLLEXPORT Variable log10(const Variable &x)
Definition Variable.hpp:373
SLEIPNIR_DLLEXPORT Variable acos(const Variable &x)
Definition Variable.hpp:270
Definition Variable.hpp:547
EqualityConstraints(std::initializer_list< EqualityConstraints > equalityConstraints)
Definition Variable.hpp:556
EqualityConstraints(LHS &&lhs, RHS &&rhs)
Definition Variable.hpp:593
EqualityConstraints(const std::vector< EqualityConstraints > &equalityConstraints)
Definition Variable.hpp:571
small_vector< Variable > constraints
A vector of scalar equality constraints.
Definition Variable.hpp:549
Definition Variable.hpp:609
small_vector< Variable > constraints
A vector of scalar inequality constraints.
Definition Variable.hpp:611
InequalityConstraints(std::initializer_list< InequalityConstraints > inequalityConstraints)
Definition Variable.hpp:619
InequalityConstraints(LHS &&lhs, RHS &&rhs)
Definition Variable.hpp:657
InequalityConstraints(const std::vector< InequalityConstraints > &inequalityConstraints)
Definition Variable.hpp:635