3 // Cassowary Incremental Constraint Solver
4 // Original Smalltalk Implementation by Alan Borning
5 // This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
6 // http://www.cs.washington.edu/homes/gjb
7 // (C) 1998, 1999 Greg J. Badros and Alan Borning
8 // See ../LICENSE for legal details regarding this software
10 // ClLinearExpression.h
12 #ifndef ClLinearExpression_H
13 #define ClLinearExpression_H
15 #if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
16 #include <cassowary/config-inline.h>
17 #define CONFIG_INLINE_H_INCLUDED
20 #include "Cassowary.h"
22 #include "ClVariable.h"
23 #include "ClLinearExpression_fwd.h"
25 class ClSimplexSolver;
27 class ClSymbolicWeight;
29 ClLinearExpression &cleNil();
32 class ClGenericLinearExpression {
34 typedef std::map<ClVariable,T> ClVarToCoeffMap;
36 // convert Number-s into ClLinearExpression-s
37 ClGenericLinearExpression(T num = 0.0);
39 // Convert from ClVariable to a ClLinearExpression
40 // this replaces ClVariable::asLinearExpression
41 ClGenericLinearExpression(ClVariable clv, T value = 1.0, T constant = 0.0);
44 ClGenericLinearExpression(const ClGenericLinearExpression<T> &expr) :
45 _constant(expr._constant),
49 virtual ~ClGenericLinearExpression();
51 // Return a new linear expression formed by multiplying self by x.
52 // (Note that this result must be linear.)
53 ClGenericLinearExpression<T> Times(Number x) const;
55 // Return a new linear expression formed by multiplying self by x.
56 // (Note that this result must be linear.)
57 ClGenericLinearExpression<T> Times(const ClGenericLinearExpression<T> &expr) const;
59 // Return a new linear expression formed by adding x to self.
60 ClGenericLinearExpression<T> Plus(const ClGenericLinearExpression<T> &expr) const;
62 // Return a new linear expression formed by subtracting x from self.
63 ClGenericLinearExpression<T> Minus(const ClGenericLinearExpression<T> &expr) const;
65 // Return a new linear expression formed by dividing self by x.
66 // (Note that this result must be linear.)
67 ClGenericLinearExpression<T> Divide(Number x) const;
71 // Return a new linear expression formed by multiplying self by x.
72 // (Note that this result must be linear.)
73 ClGenericLinearExpression<T> *P_times(Number x) const
74 { return new ClGenericLinearExpression<T>(Times(x)); }
76 // Return a new linear expression formed by adding x to self.
77 ClGenericLinearExpression<T> *P_plus(const ClGenericLinearExpression<T> &expr) const
78 { return new ClGenericLinearExpression<T>(Plus(expr)); }
80 // Return a new linear expression formed by subtracting x from self.
81 ClGenericLinearExpression<T> *P_minus(const ClGenericLinearExpression<T> &expr) const
82 { return new ClGenericLinearExpression<T>(Minus(expr)); }
84 // Return a new linear expression formed by dividing self by x.
85 // (Note that this result must be linear.)
86 ClGenericLinearExpression<T> *P_divide(Number x) const
87 { return new ClGenericLinearExpression<T>(Divide(x)); }
89 // Return a new linear expression formed by dividing self by x.
90 // (Note that this result must be linear.)
91 ClGenericLinearExpression<T> Divide(const ClGenericLinearExpression<T> &expr) const;
93 // Return a new linear expression (aNumber/this). Since the result
94 // must be linear, this is permissible only if 'this' is a constant.
95 ClGenericLinearExpression<T> DivFrom(const ClGenericLinearExpression<T> &expr) const;
97 // Return a new linear expression (aNumber-this).
98 ClGenericLinearExpression<T> SubtractFrom(const ClGenericLinearExpression<T> &expr) const
99 { return expr.Minus(*this); }
101 // Add n*expr to this expression from another expression expr.
102 ClGenericLinearExpression<T> &AddExpression(const ClGenericLinearExpression<T> &expr,
105 // Add n*expr to this expression from another expression expr.
106 // Notify the solver if a variable is added or deleted from this
108 ClGenericLinearExpression<T> &AddExpression(const ClGenericLinearExpression<T> &expr, Number n,
112 // Add a term c*v to this expression. If the expression already
113 // contains a term involving v, Add c to the existing coefficient.
114 // If the new coefficient is approximately 0, delete v.
115 ClGenericLinearExpression<T> &AddVariable(ClVariable v, T c = 1.0);
117 // Add a term c*v to this expression. If the expression already
118 // contains a term involving v, Add c to the existing coefficient.
119 // If the new coefficient is approximately 0, delete v.
120 ClGenericLinearExpression<T> &setVariable(ClVariable v, T c)
121 {assert(c != 0.0); _terms[v] = c; return *this; }
123 // Add a term c*v to this expression. If the expression already
124 // contains a term involving v, Add c to the existing coefficient.
125 // If the new coefficient is approximately 0, delete v. Notify the
126 // solver if v appears or disappears from this expression.
127 ClGenericLinearExpression<T> &AddVariable(ClVariable v, T c,
131 // Return a pivotable variable in this expression. (It is an error
132 // if this expression is constant -- signal ExCLInternalError in
133 // that case). Return NULL if no pivotable variables
134 ClVariable AnyPivotableVariable() const;
136 // Replace var with a symbolic expression expr that is equal to it.
137 // If a variable has been added to this expression that wasn't there
138 // before, or if a variable has been dropped from this expression
139 // because it now has a coefficient of 0, inform the solver.
141 // var occurs with a non-Zero coefficient in this expression.
142 void SubstituteOut(ClVariable v,
143 const ClGenericLinearExpression<T> &expr,
147 // This linear expression currently represents the equation
148 // oldSubject=self. Destructively modify it so that it represents
149 // the equation NewSubject=self.
151 // Precondition: NewSubject currently has a nonzero coefficient in
155 // Suppose this expression is c + a*NewSubject + a1*v1 + ... + an*vn.
157 // Then the current equation is
158 // oldSubject = c + a*NewSubject + a1*v1 + ... + an*vn.
159 // The new equation will be
160 // NewSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn.
161 // Note that the term involving NewSubject has been dropped.
162 void ChangeSubject(ClVariable old_subject,
163 ClVariable new_subject);
165 // This linear expression currently represents the equation self=0. Destructively modify it so
166 // that subject=self represents an equivalent equation.
168 // Precondition: subject must be one of the variables in this expression.
170 // Suppose this expression is
171 // c + a*subject + a1*v1 + ... + an*vn
173 // c + a*subject + a1*v1 + ... + an*vn = 0
174 // The modified expression will be
175 // subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
177 // subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
179 // Note that the term involving subject has been dropped.
180 // Returns the reciprocal, so ChangeSubject can use it, too
181 T NewSubject(ClVariable subject);
183 // Return the value of the linear expression
184 // given the current assignments of values to contained variables
187 // Return the coefficient corresponding to variable var, i.e.,
188 // the 'ci' corresponding to the 'vi' that var is:
189 // v1*c1 + v2*c2 + .. + vn*cn + c
190 T CoefficientFor(ClVariable var) const
192 typename ClVarToCoeffMap::const_iterator it = _terms.find(var);
193 if (it != _terms.end())
199 { return _constant; }
201 void Set_constant(T c)
204 const ClVarToCoeffMap &Terms() const
207 ClVarToCoeffMap &Terms()
210 void IncrementConstant(T c)
213 bool IsConstant() const
214 { return _terms.size() == 0; }
217 virtual ostream &PrintOn(ostream &xo) const;
219 friend ostream &operator<<(ostream &xo,const ClGenericLinearExpression<T> &cle)
220 { return cle.PrintOn(xo); }
223 friend ClGenericLinearExpression<T> operator+(const ClGenericLinearExpression<T> &e1,
224 const ClGenericLinearExpression<T> &e2)
225 { return e1.Plus(e2); }
227 friend ClGenericLinearExpression<T> operator-(const ClGenericLinearExpression<T> &e1,
228 const ClGenericLinearExpression<T> &e2)
229 { return e1.Minus(e2); }
231 friend ClGenericLinearExpression<T> operator*(const ClGenericLinearExpression<T> &e1,
232 const ClGenericLinearExpression<T> &e2)
233 { return e1.Times(e2); }
236 friend ClGenericLinearExpression<T> operator/(const ClGenericLinearExpression<T> &e1,
237 const ClGenericLinearExpression<T> &e2)
238 { return e1.Divide(e2); }
240 // FIXGJB -- this may be wrong -- should test underlying expression for equality
241 friend bool operator==(const ClGenericLinearExpression<T> &e1,
242 const ClGenericLinearExpression<T> &e2)
243 { return &e1 == &e2; }
245 /// Named versions of the operator functions for ease of
246 /// wrapping, or expressing using prefix notation
248 friend ClGenericLinearExpression<T> Plus(const ClGenericLinearExpression<T> &e1,
249 const ClGenericLinearExpression<T> &e2)
250 { return e1.Plus(e2); }
252 friend ClGenericLinearExpression<T> Minus(const ClGenericLinearExpression<T> &e1,
253 const ClGenericLinearExpression<T> &e2)
254 { return e1.Minus(e2); }
256 friend ClGenericLinearExpression<T> Times(const ClGenericLinearExpression<T> &e1,
257 const ClGenericLinearExpression<T> &e2)
258 { return e1.Times(e2); }
261 friend ClGenericLinearExpression<T> *Divide(const ClGenericLinearExpression<T> &e1,
262 const ClGenericLinearExpression<T> &e2)
263 { return new ClGenericLinearExpression<T>(e1.Divide(e2)); }
265 friend ClGenericLinearExpression<T> *p_Plus(const ClGenericLinearExpression<T> &e1,
266 const ClGenericLinearExpression<T> &e2)
267 { return new ClGenericLinearExpression<T>(e1.Plus(e2)); }
269 friend ClGenericLinearExpression<T> *p_Minus(const ClGenericLinearExpression<T> &e1,
270 const ClGenericLinearExpression<T> &e2)
271 { return new ClGenericLinearExpression<T>(e1.Minus(e2)); }
273 friend ClGenericLinearExpression<T> *p_Times(const ClGenericLinearExpression<T> &e1,
274 const ClGenericLinearExpression<T> &e2)
275 { return new ClGenericLinearExpression<T>(e1.Times(e2)); }
277 friend ClGenericLinearExpression<T> *p_Divide(const ClGenericLinearExpression<T> &e1,
278 const ClGenericLinearExpression<T> &e2)
279 { return new ClGenericLinearExpression<T>(e1.Divide(e2)); }
282 // FIXGJB -- this may be wrong -- should test underlying expression for equality
283 friend bool FEquals(const ClGenericLinearExpression<T> &e1,
284 const ClGenericLinearExpression<T> &e2)
285 { return &e1 == &e2; }
287 ClGenericLinearExpression<T> &MultiplyMe(T x);
292 ClVarToCoeffMap _terms;
296 typedef ClGenericLinearExpression<Number>::ClVarToCoeffMap ClVarToNumberMap;