Module: Quicopt::Conditions Private
- Defined in:
- lib/quicopt/indicators.rb
Overview
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
The mapping from a comparison to its 0/1 form, and the model a term belongs to.
Class Method Summary collapse
-
.argument_key(expr) ⇒ Object
private
An expression as an interning key: its constant and its terms in model order.
-
.holds(residual, sense, tol) ⇒ Object
private
residualislhs − rhs; the result follows the table in this file's header. -
.one_minus(expr) ⇒ Object
private
1 − e. -
.owner(factors) ⇒ Object
private
The one model every factor in
factorsbelongs to. -
.term(op, argument, tol = 0.0) ⇒ Object
private
The interned
Conditionopoverargument, as an expression. -
.truth(value, sense, tol) ⇒ Object
private
Whether a comparison between two numbers (value = lhs − rhs) holds.
Class Method Details
.argument_key(expr) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
An expression as an interning key: its constant and its terms in model order. Factors are interned, so they key by identity.
140 141 142 |
# File 'lib/quicopt/indicators.rb', line 140 def argument_key(expr) [expr.constant, expr.linear.sort_by { |f, _| f.order }, expr.quadratic.sort_by { |(a, b), _| [a.order, b.order] }] end |
.holds(residual, sense, tol) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
residual is lhs − rhs; the result follows the table in this file's
header.
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/quicopt/indicators.rb', line 90 def holds(residual, sense, tol) return Expression.new(constant: truth(residual.constant, sense, tol) ? 1.0 : 0.0) if residual.constant? negated = residual.scale(-1.0) case sense when :le then term(:step, negated.plus(Expression.new(constant: tol))) when :ge then term(:step, residual.plus(Expression.new(constant: tol))) when :lt then one_minus(term(:step, residual.plus(Expression.new(constant: -tol)))) when :gt then one_minus(term(:step, negated.plus(Expression.new(constant: -tol)))) when :eq then tol.positive? ? term(:near, residual, tol) : one_minus(term(:indicator, residual)) when :ne then tol.positive? ? one_minus(term(:near, residual, tol)) : term(:indicator, residual) end end |
.one_minus(expr) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1 − e.
124 125 126 |
# File 'lib/quicopt/indicators.rb', line 124 def one_minus(expr) Expression.new(constant: 1.0).plus(expr.scale(-1.0)) end |
.owner(factors) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The one model every factor in factors belongs to.
131 132 133 134 135 136 |
# File 'lib/quicopt/indicators.rb', line 131 def owner(factors) models = factors.map(&:model).uniq(&:object_id) raise ArgumentError, "the terms of one expression belong to different Quicopt::Models" if models.size > 1 models.first end |
.term(op, argument, tol = 0.0) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The interned Condition op over argument, as an expression.
117 118 119 120 121 |
# File 'lib/quicopt/indicators.rb', line 117 def term(op, argument, tol = 0.0) model = owner(argument.factors) key = [:condition, op, argument_key(argument), tol] Expression.new(linear: { model.intern(key) { Condition.new(model, op, argument, tol, model.next_order) } => 1.0 }) end |
.truth(value, sense, tol) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Whether a comparison between two numbers (value = lhs − rhs) holds.
105 106 107 108 109 110 111 112 113 114 |
# File 'lib/quicopt/indicators.rb', line 105 def truth(value, sense, tol) case sense when :le then -value + tol >= 0 when :ge then value + tol >= 0 when :lt then (value - tol).negative? when :gt then (-value - tol).negative? when :eq then tol.positive? ? value.abs <= tol : value.zero? when :ne then tol.positive? ? value.abs > tol : !value.zero? end end |