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
14 #include <cassowary/ClTableau.h>
15 #include <cassowary/debug.h>
19 #define CONFIG_H_INCLUDED
23 // delete the linear expressions
24 // let ClSimplexSolver worry about deleting the variables
25 ClTableau::~ClTableau()
27 ClTableauRowsMap::iterator it = _rows.begin();
28 for (; it != _rows.end(); ++it)
30 // free the ClLinearExpression that we new-ed
32 cerr << "Deleting row delete@ " << ((*it).second) << endl;
39 // Some extra debugging info
41 ClTableau::PrintInternalInfo(ostream &xo) const
43 xo << "ncns:" << _rows.size() -1
44 << "; cols:" << _columns.size()
45 << "; infrows:" << _infeasibleRows.size()
46 << "; ebvars:" << _externalRows.size()
47 << "; epvars:" << _externalParametricVars.size();
53 ClTableau::printExternalVariablesTo(ostream &xo) const
56 ClVarSet::iterator itParVars = _externalParametricVars.begin();
57 for ( ; itParVars != _externalParametricVars.end(); ++itParVars ) {
58 ClVariable v = *itParVars;
62 ClVarSet::iterator itRowVars = _externalRows.begin();
63 for ( ; itRowVars != _externalRows.end() ; ++itRowVars ) {
64 ClVariable v = *itRowVars;
73 // Add v, update column cross indices
74 // v becomes a basic variable
75 // expr is now owned by ClTableau class,
76 // and ClTableauis responsible for deleting it
77 // (also, expr better be allocated on the heap!)
79 ClTableau::addRow(ClVariable var, const ClLinearExpression &expr)
82 Tracer TRACER(__FUNCTION__);
83 cerr << "(" << var << ", " << expr << ")" << endl;
85 _rows[var] = const_cast<ClLinearExpression *>(&expr);
86 ClVarToNumberMap::const_iterator it = expr.Terms().begin();
87 // for each variable in expr, Add var to the set of rows which have that variable
88 // in their Expression
89 for (; it != expr.Terms().end(); ++it)
91 ClVariable v = (*it).first;
92 _columns[v].insert(var);
93 if (v.IsExternal() && !FIsBasicVar(v))
95 _externalParametricVars.insert(v);
100 _externalRows.insert(var);
103 cerr << *this << endl;
107 // Remove var from the tableau -- remove the column cross indices for var
108 // and remove var from every Expression in rows in which v occurs
109 // Remove the parametric variable var, updating the appropriate column and row entries.
110 // (Renamed from Smalltalk implementation's `removeParametricVar')
112 ClTableau::RemoveColumn(ClVariable var)
115 Tracer TRACER(__FUNCTION__);
116 cerr << "(" << var << ")" << endl;
118 ClTableauColumnsMap::iterator it_var = _columns.find(var);
119 if (it_var == _columns.end())
120 return var; // nothing to do
122 ClVarSet &varset = (*it_var).second;
123 // remove the rows with the variables in varset
124 ClVarSet::iterator it = varset.begin();
125 for (; it != varset.end(); ++it)
127 ClVariable v = (*it);
128 ClVarToNumberMap &Terms = _rows[v]->Terms();
129 Terms.erase(Terms.find(var));
131 if (var.IsExternal())
133 _externalRows.erase(var);
134 _externalParametricVars.erase(var);
136 _columns.erase(it_var);
140 // Remove the basic variable v from the tableau row v=expr
141 // Then update column cross indices
143 ClTableau::RemoveRow(ClVariable var)
146 Tracer TRACER(__FUNCTION__);
147 cerr << "(" << var << ")" << endl;
149 ClTableauRowsMap::iterator it = _rows.find(var);
150 assert(it != _rows.end());
151 ClLinearExpression *pexpr = (*it).second;
152 ClVarToNumberMap &Terms = pexpr->Terms();
153 ClVarToNumberMap::iterator it_term = Terms.begin();
154 for (; it_term != Terms.end(); ++it_term)
156 ClVariable v = (*it_term).first;
157 _columns[v].erase(var);
158 if (_columns[v].size() == 0)
161 _externalParametricVars.erase(v);
165 _infeasibleRows.erase(var);
167 if (var.IsExternal())
169 _externalRows.erase(var);
170 _externalParametricVars.erase(var);
175 cerr << "- returning " << *pexpr << endl;
180 // Replace all occurrences of oldVar with expr, and update column cross indices
181 // oldVar should now be a basic variable
182 // Uses the Columns data structure and calls SubstituteOut on each
183 // row that has oldVar in it
184 // oldVar is leaving the basis, and becoming parametric
186 ClTableau::SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr)
189 cerr << "* ClTableau::";
190 Tracer TRACER(__FUNCTION__);
191 cerr << "(" << oldVar << ", " << expr << ")" << endl;
192 cerr << (*this) << endl;
195 ClTableauColumnsMap::iterator it_oldVar = _columns.find(oldVar);
196 if (it_oldVar == _columns.end())
199 ClVarSet &varset = (*it_oldVar).second;
200 ClVarSet::iterator it = varset.begin();
201 for (; it != varset.end(); ++it)
203 ClVariable v = (*it);
204 ClLinearExpression *prow = _rows[v];
205 prow->SubstituteOut(oldVar,expr,v,*this);
206 if (v.IsRestricted() && prow->Constant() < 0.0)
208 _infeasibleRows.insert(v);
211 _columns.erase(it_oldVar);
212 if (oldVar.IsExternal())
214 if (_columns[oldVar].size() > 0)
216 _externalRows.insert(oldVar);
218 _externalParametricVars.erase(oldVar);
226 PrintTo(ostream &xo, const ClVarSet & varset)
228 ClVarSet::const_iterator it = varset.begin();
230 if (it != varset.end())
235 for (; it != varset.end(); ++it)
243 ostream &operator<<(ostream &xo, const ClVarSet & varset)
244 { return PrintTo(xo,varset); }
247 PrintTo(ostream &xo, const ClTableauColumnsMap & varmap)
249 ClTableauColumnsMap::const_iterator it = varmap.begin();
250 for (; it != varmap.end(); ++it)
252 xo << (*it).first << " -> " << (*it).second << endl;
257 ostream &operator<<(ostream &xo, const ClTableauColumnsMap & varmap)
258 { return PrintTo(xo,varmap); }
261 PrintTo(ostream &xo, const ClTableauRowsMap & rows)
263 ClTableauRowsMap::const_iterator it = rows.begin();
264 for (; it != rows.end(); ++it)
266 ClVariable v = it->first;
267 const ClLinearExpression *pe = it->second;
268 xo << v << " <-=-> ";
269 if (pe) xo << *pe; else xo << "NilExpr";
275 ostream &operator<<(ostream &xo, const ClTableauRowsMap & rows)
276 { return PrintTo(xo,rows); }
279 ClTableau::PrintOn(ostream &xo) const
285 xo << "Infeasible rows: "
286 << _infeasibleRows << endl;
287 xo << "External basic variables: "
288 << _externalRows << endl;
289 xo << "External parametric variables: "
290 << _externalParametricVars << endl;
294 ostream &operator<<(ostream &xo, const ClTableau &clt)
295 { return clt.PrintOn(xo); }