21#include "absl/base/attributes.h"
29constexpr double kInf = std::numeric_limits<double>::infinity();
31#ifdef MATH_OPT_USE_EXPRESSION_COUNTERS
36 ++num_calls_copy_constructor_;
39LinearExpression::LinearExpression(LinearExpression&& other)
40 : terms_(
std::move(other.terms_)),
42 ++num_calls_move_constructor_;
45LinearExpression& LinearExpression::operator=(
const LinearExpression& other) {
46 terms_ = other.terms_;
51ABSL_CONST_INIT
thread_local int
52 LinearExpression::num_calls_default_constructor_ = 0;
53ABSL_CONST_INIT
thread_local int LinearExpression::num_calls_copy_constructor_ =
55ABSL_CONST_INIT
thread_local int LinearExpression::num_calls_move_constructor_ =
57ABSL_CONST_INIT
thread_local int
58 LinearExpression::num_calls_initializer_list_constructor_ = 0;
60void LinearExpression::ResetCounters() {
61 num_calls_default_constructor_ = 0;
62 num_calls_copy_constructor_ = 0;
63 num_calls_move_constructor_ = 0;
64 num_calls_initializer_list_constructor_ = 0;
68double LinearExpression::Evaluate(
70 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
75 for (
const auto& [variable_id,
coef] : terms_.raw_map()) {
76 result +=
coef * variable_values.
raw_map().at(variable_id);
81double LinearExpression::EvaluateWithDefaultZero(
83 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
88 for (
const auto& [variable_id,
coef] : terms_.raw_map()) {
102struct LeadingCoefficientFormatter {
103 LeadingCoefficientFormatter(
const double coeff,
const bool is_first)
110 const LeadingCoefficientFormatter formatter) {
111 const double coeff = formatter.coeff;
112 if (formatter.is_first) {
115 }
else if (
coeff == -1.0) {
123 }
else if (
coeff == -1.0) {
125 }
else if (std::isnan(
coeff)) {
127 }
else if (
coeff >= 0) {
128 out <<
" + " <<
coeff <<
"*";
130 out <<
" - " << -
coeff <<
"*";
137struct ConstantFormatter {
144std::ostream&
operator<<(std::ostream& out,
const ConstantFormatter formatter) {
145 const double constant = formatter.constant;
146 if (formatter.is_first) {
169 const std::vector<Variable> sorted_variables = expression.terms_.SortedKeys();
171 for (
const auto v : sorted_variables) {
172 const double coeff = expression.terms_.at(v);
174 ostr << LeadingCoefficientFormatter(
coeff, first) << v;
178 ostr << ConstantFormatter(expression.
offset(), first);
190 ostr << bounded_expression.
expression <<
" = " << lb;
191 }
else if (lb == -
kInf) {
192 ostr << bounded_expression.
expression <<
" ≤ " << ub;
193 }
else if (ub ==
kInf) {
194 ostr << bounded_expression.
expression <<
" ≥ " << lb;
196 ostr << lb <<
" ≤ " << bounded_expression.
expression <<
" ≤ " << ub;
201double QuadraticExpression::Evaluate(
203 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
207 double result = offset();
208 for (
const auto& [variable_id,
coef] : linear_terms_.raw_map()) {
209 result +=
coef * variable_values.
raw_map().at(variable_id);
218double QuadraticExpression::EvaluateWithDefaultZero(
220 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
224 double result = offset();
225 for (
const auto& [variable_id,
coef] : linear_terms_.raw_map()) {
246 ostr << LeadingCoefficientFormatter(
coeff, first);
252 v.typed_id().second);
253 if (first_variable == second_variable) {
254 ostr << first_variable <<
"²";
256 ostr << first_variable <<
"*" << second_variable;
262 ostr << LeadingCoefficientFormatter(
coeff, first) << v;
266 ostr << ConstantFormatter(expr.
offset(), first);
270#ifdef MATH_OPT_USE_EXPRESSION_COUNTERS
271QuadraticExpression::QuadraticExpression() { ++num_calls_default_constructor_; }
273QuadraticExpression::QuadraticExpression(
const QuadraticExpression& other)
274 : quadratic_terms_(other.quadratic_terms_),
275 linear_terms_(other.linear_terms_),
277 ++num_calls_copy_constructor_;
281 : quadratic_terms_(
std::move(other.quadratic_terms_)),
282 linear_terms_(
std::move(other.linear_terms_)),
284 ++num_calls_move_constructor_;
287QuadraticExpression& QuadraticExpression::operator=(
288 const QuadraticExpression& other) {
289 quadratic_terms_ = other.quadratic_terms_;
290 linear_terms_ = other.linear_terms_;
291 offset_ = other.offset_;
295ABSL_CONST_INIT
thread_local int
296 QuadraticExpression::num_calls_default_constructor_ = 0;
297ABSL_CONST_INIT
thread_local int
298 QuadraticExpression::num_calls_copy_constructor_ = 0;
299ABSL_CONST_INIT
thread_local int
300 QuadraticExpression::num_calls_move_constructor_ = 0;
301ABSL_CONST_INIT
thread_local int
302 QuadraticExpression::num_calls_initializer_list_constructor_ = 0;
303ABSL_CONST_INIT
thread_local int
304 QuadraticExpression::num_calls_linear_expression_constructor_ = 0;
306void QuadraticExpression::ResetCounters() {
307 num_calls_default_constructor_ = 0;
308 num_calls_copy_constructor_ = 0;
309 num_calls_move_constructor_ = 0;
310 num_calls_initializer_list_constructor_ = 0;
311 num_calls_linear_expression_constructor_ = 0;
#define CHECK_EQ(val1, val2)
const StorageType & raw_map() const
const ModelStorage * storage() const
LinearExpression()=default
const QuadraticTermMap< double > & quadratic_terms() const
QuadraticExpression()=default
const VariableMap< double > & linear_terms() const
absl::Span< const int64_t > variable_ids
const Collection::value_type::second_type & FindWithDefault(const Collection &collection, const typename Collection::value_type::first_type &key, const typename Collection::value_type::second_type &value)
constexpr absl::string_view kObjectsFromOtherModelStorage
Collection of objects used to extend the Constraint Solver library.
std::ostream & operator<<(std::ostream &out, const Assignment &assignment)
LinearExpression expression