summaryrefslogtreecommitdiff
path: root/libs/cassowary/cassowary/ClTableau.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cassowary/cassowary/ClTableau.h')
-rw-r--r--libs/cassowary/cassowary/ClTableau.h230
1 files changed, 230 insertions, 0 deletions
diff --git a/libs/cassowary/cassowary/ClTableau.h b/libs/cassowary/cassowary/ClTableau.h
new file mode 100644
index 0000000000..117ed0fb9d
--- /dev/null
+++ b/libs/cassowary/cassowary/ClTableau.h
@@ -0,0 +1,230 @@
+// $Id$
+//
+// Cassowary Incremental Constraint Solver
+// Original Smalltalk Implementation by Alan Borning
+// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
+// http://www.cs.washington.edu/homes/gjb
+// (C) 1998, 1999 Greg J. Badros and Alan Borning
+// See ../LICENSE for legal details regarding this software
+//
+// ClTableau.h
+
+#ifndef ClTableau_H
+#define ClTableau_H
+
+#include <iostream>
+
+#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
+#include <cassowary/config-inline.h>
+#define CONFIG_INLINE_H_INCLUDED
+#endif
+
+#include "Cassowary.h"
+#include "ClLinearExpression.h"
+#include "ClVariable.h"
+#include "ClTypedefs.h"
+
+
+#ifndef CL_NO_IO
+class ClTableau;
+
+ostream &operator<<(ostream &xo, const ClTableau &clt);
+
+ostream &operator<<(ostream &xo, const ClVarSet &varset);
+
+ostream &operator<<(ostream &xo, const ClTableauColumnsMap &varmap);
+
+ostream &operator<<(ostream &xo, const ClTableauRowsMap &rows);
+
+ostream &operator<<(ostream &xo, const ClVarVector &varlist);
+#endif // CL_NO_IO
+
+class ClTableau {
+
+ public:
+ // No public constructor, since this does nothing but support
+ // an ADT for the ClSimplexSolver
+
+ // Variable v has been removed from an Expression. If the
+ // Expression is in a tableau the corresponding basic variable is
+ // subject (or if subject is nil then it's in the objective function).
+ // Update the column cross-indices.
+ void NoteRemovedVariable(ClVariable v, ClVariable subject)
+ {
+#ifdef CL_TRACE
+ Tracer TRACER(__FUNCTION__);
+ std::cerr << "(" << v << ", " << subject << ")" << std::endl;
+#endif
+ ClVarSet &column = _columns[v];
+ ClVarSet::const_iterator it = column.find(subject);
+ assert(it != column.end());
+ column.erase(it);
+#ifdef CL_TRACE_VERBOSE
+ std::cerr << "v = " << v << " and Columns[v].size() = "
+ << column.size() << std::endl;
+#endif
+ if (column.size() == 0)
+ {
+ _columns.erase(v);
+ _externalRows.erase(v);
+ _externalParametricVars.erase(v);
+ }
+ }
+
+ // v has been added to the linear Expression for subject
+ // update column cross indices
+ void NoteAddedVariable(ClVariable v, ClVariable subject)
+ {
+#ifdef CL_TRACE
+ Tracer TRACER(__FUNCTION__);
+ std::cerr << "(" << v << ", " << subject << ")" << std::endl;
+#endif
+ _columns[v].insert(subject);
+ if (v.IsExternal() && !FIsBasicVar(v))
+ {
+ _externalParametricVars.insert(v);
+ }
+ }
+
+#ifndef CL_NO_IO
+ std::ostream &PrintOn(ostream &xo) const;
+
+ ostream &PrintInternalInfo(ostream &xo) const;
+
+ ostream &printExternalVariablesTo(ostream &xo) const;
+
+#endif
+
+ // Check integrity of the tableau
+ // not complete, yet, but a start, at least
+ // Guard calls to AssertValid with CL_SOLVER_CHECK_INTEGRITY,
+ // since this is expensive
+ virtual void AssertValid() const {
+#ifndef NDEBUG
+ // all external basic variables are in _externalRows
+ // and all external parametric variables are in _externalParametricVars
+ ClTableauRowsMap::const_iterator itRow = _rows.begin();
+ for (; itRow != _rows.end(); ++itRow)
+ {
+ const ClVariable clv = (*itRow).first;
+ if (clv.IsExternal())
+ {
+ if (_externalRows.find(clv) == _externalRows.end())
+ {
+#ifndef CL_NO_IO
+ std::cerr << "External basic variable " << clv
+ << " is not in _externalRows" << std::endl;
+#endif
+ }
+ }
+ const ClLinearExpression *pcle = RowExpression(clv);
+ assert(pcle);
+ ClVarToNumberMap::const_iterator it = pcle->Terms().begin();
+ for (; it != pcle->Terms().end(); ++it)
+ {
+ ClVariable clv = (*it).first;
+ if (clv.IsExternal())
+ {
+ if (_externalParametricVars.find(clv) == _externalParametricVars.end())
+ {
+#ifndef CL_NO_IO
+ std::cerr << "External parametric variable " << clv
+ << " is not in _externalParametricVars" << std::endl;
+#endif
+ }
+ }
+ }
+ }
+#endif /* !NDEBUG */
+ }
+
+
+ protected:
+ // Constructor -- want to start with empty objects so not much to do
+ ClTableau()
+ { }
+
+ virtual ~ClTableau();
+
+ // Add v=expr to the tableau, update column cross indices
+ // v becomes a basic variable
+ // expr is now owned by ClTableau class,
+ // and ClTableauis responsible for deleting it
+ // (also, expr better be allocated on the heap!)
+ void addRow(ClVariable v, const ClLinearExpression &expr);
+
+ // Remove v from the tableau -- remove the column cross indices for v
+ // and remove v from every Expression in rows in which v occurs
+ // returns a pointer to the variable (since we often want to delete
+ // the variable)
+ ClVariable RemoveColumn(ClVariable v);
+
+ // Remove the basic variable v from the tableau row v=expr
+ // Then update column cross indices
+ // Probably want to call delete on the ClLinearExpression * returned
+ // unless you're adding that same Expression back into the
+ // tableau
+ ClLinearExpression *RemoveRow(ClVariable v);
+
+ // Replace all occurrences of oldVar with expr, and update column cross indices
+ // oldVar should now be a basic variable
+ void SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr);
+
+ ClTableauColumnsMap Columns()
+ { return _columns; }
+
+ ClTableauRowsMap Rows()
+ { return _rows; }
+
+ // return true iff the variable subject is in the Columns keys
+ bool ColumnsHasKey(ClVariable subject) const
+ {
+ ClTableauColumnsMap::const_iterator i = _columns.find(subject);
+ return (i != _columns.end());
+ }
+
+ const ClLinearExpression *RowExpression(ClVariable v) const
+ {
+ ClTableauRowsMap::const_iterator i = _rows.find(v);
+ if (i != _rows.end())
+ return (*i).second;
+ else
+ return 0;
+ }
+
+ ClLinearExpression *RowExpression(ClVariable v)
+ {
+ const ClTableau *pthis = const_cast<const ClTableau *>(this);
+ return const_cast<ClLinearExpression *>(pthis->RowExpression(v));
+ }
+
+
+ bool FIsBasicVar(ClVariable v)
+ { return RowExpression(v) != 0; }
+
+ // private: FIXGJB: can I improve the encapsulation?
+
+ // _columns is a mapping from variables which occur in expressions to the
+ // set of basic variables whose expressions contain them
+ // i.e., it's a mapping from variables in expressions (a column) to the
+ // set of rows that contain them
+ ClTableauColumnsMap _columns;
+
+ // _rows maps basic variables to the expressions for that row in the tableau
+ ClTableauRowsMap _rows;
+
+ // the collection of basic variables that have infeasible rows
+ // (used when reoptimizing)
+ ClVarSet _infeasibleRows;
+
+ // the set of rows where the basic variable is external
+ // this was added to the C++ version to reduce time in SetExternalVariables()
+ ClVarSet _externalRows;
+
+ // the set of external variables which are parametric
+ // this was added to the C++ version to reduce time in SetExternalVariables()
+ ClVarSet _externalParametricVars;
+
+};
+
+#endif