28constexpr double kInf = std::numeric_limits<double>::infinity();
30#ifdef MATH_OPT_USE_EXPRESSION_COUNTERS
35 ++num_calls_copy_constructor_;
38LinearExpression::LinearExpression(LinearExpression&& other)
39 : terms_(
std::move(other.terms_)),
41 ++num_calls_move_constructor_;
44LinearExpression& LinearExpression::operator=(
const LinearExpression& other) {
45 terms_ = other.terms_;
50ABSL_CONST_INIT
thread_local int
51 LinearExpression::num_calls_default_constructor_ = 0;
52ABSL_CONST_INIT
thread_local int LinearExpression::num_calls_copy_constructor_ =
54ABSL_CONST_INIT
thread_local int LinearExpression::num_calls_move_constructor_ =
56ABSL_CONST_INIT
thread_local int
57 LinearExpression::num_calls_initializer_list_constructor_ = 0;
59void LinearExpression::ResetCounters() {
60 num_calls_default_constructor_ = 0;
61 num_calls_copy_constructor_ = 0;
62 num_calls_move_constructor_ = 0;
63 num_calls_initializer_list_constructor_ = 0;
67double LinearExpression::Evaluate(
69 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
74 for (
const auto& [variable_id,
coef] : terms_.raw_map()) {
75 result +=
coef * variable_values.
raw_map().at(variable_id);
80double LinearExpression::EvaluateWithDefaultZero(
82 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
87 for (
const auto& [variable_id,
coef] : terms_.raw_map()) {
101struct LeadingCoefficientFormatter {
102 LeadingCoefficientFormatter(
const double coeff,
const bool is_first)
109 const LeadingCoefficientFormatter formatter) {
110 const double coeff = formatter.coeff;
111 if (formatter.is_first) {
114 }
else if (
coeff == -1.0) {
122 }
else if (
coeff == -1.0) {
124 }
else if (std::isnan(
coeff)) {
126 }
else if (
coeff >= 0) {
127 out <<
" + " <<
coeff <<
"*";
129 out <<
" - " << -
coeff <<
"*";
136struct ConstantFormatter {
143std::ostream&
operator<<(std::ostream& out,
const ConstantFormatter formatter) {
144 const double constant = formatter.constant;
145 if (formatter.is_first) {
168 const std::vector<Variable> sorted_variables = expression.terms_.SortedKeys();
170 for (
const auto v : sorted_variables) {
171 const double coeff = expression.terms_.at(v);
173 ostr << LeadingCoefficientFormatter(
coeff, first) << v;
177 ostr << ConstantFormatter(expression.
offset(), first);
189 ostr << bounded_expression.
expression <<
" = " << lb;
190 }
else if (lb == -
kInf) {
191 ostr << bounded_expression.
expression <<
" ≤ " << ub;
192 }
else if (ub ==
kInf) {
193 ostr << bounded_expression.
expression <<
" ≥ " << lb;
195 ostr << lb <<
" ≤ " << bounded_expression.
expression <<
" ≤ " << ub;
200double QuadraticExpression::Evaluate(
202 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
206 double result = offset();
207 for (
const auto& [variable_id,
coef] : linear_terms_.raw_map()) {
208 result +=
coef * variable_values.
raw_map().at(variable_id);
217double QuadraticExpression::EvaluateWithDefaultZero(
219 if (variable_values.
storage() !=
nullptr && storage() !=
nullptr) {
223 double result = offset();
224 for (
const auto& [variable_id,
coef] : linear_terms_.raw_map()) {
245 ostr << LeadingCoefficientFormatter(
coeff, first);
251 v.typed_id().second);
252 if (first_variable == second_variable) {
253 ostr << first_variable <<
"²";
255 ostr << first_variable <<
"*" << second_variable;
261 ostr << LeadingCoefficientFormatter(
coeff, first) << v;
265 ostr << ConstantFormatter(expr.
offset(), first);
269#ifdef MATH_OPT_USE_EXPRESSION_COUNTERS
270QuadraticExpression::QuadraticExpression() { ++num_calls_default_constructor_; }
272QuadraticExpression::QuadraticExpression(
const QuadraticExpression& other)
273 : quadratic_terms_(other.quadratic_terms_),
274 linear_terms_(other.linear_terms_),
276 ++num_calls_copy_constructor_;
280 : quadratic_terms_(
std::move(other.quadratic_terms_)),
281 linear_terms_(
std::move(other.linear_terms_)),
283 ++num_calls_move_constructor_;
286QuadraticExpression& QuadraticExpression::operator=(
287 const QuadraticExpression& other) {
288 quadratic_terms_ = other.quadratic_terms_;
289 linear_terms_ = other.linear_terms_;
290 offset_ = other.offset_;
294ABSL_CONST_INIT
thread_local int
295 QuadraticExpression::num_calls_default_constructor_ = 0;
296ABSL_CONST_INIT
thread_local int
297 QuadraticExpression::num_calls_copy_constructor_ = 0;
298ABSL_CONST_INIT
thread_local int
299 QuadraticExpression::num_calls_move_constructor_ = 0;
300ABSL_CONST_INIT
thread_local int
301 QuadraticExpression::num_calls_initializer_list_constructor_ = 0;
302ABSL_CONST_INIT
thread_local int
303 QuadraticExpression::num_calls_linear_expression_constructor_ = 0;
305void QuadraticExpression::ResetCounters() {
306 num_calls_default_constructor_ = 0;
307 num_calls_copy_constructor_ = 0;
308 num_calls_move_constructor_ = 0;
309 num_calls_initializer_list_constructor_ = 0;
310 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