hrev43369 adds 2 changesets to branch 'master' old head: b394b1d2bb311256614713abe6a9184b440e3c30 new head: 056207eedd7703fb5d2941ef2a007c883deaab25 ---------------------------------------------------------------------------- 57014d1: Make tabs BReferenceable. Maintain a list of tabs. 056207e: Cleanup the constraint solver a bit and fix a bug when a variable is removed. [ czeidler <haiku@xxxxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 15 files changed, 254 insertions(+), 116 deletions(-) headers/libs/alm/ALMLayout.h | 26 +++++-- headers/libs/alm/Area.h | 12 ++-- headers/libs/alm/Column.h | 4 +- headers/libs/alm/Row.h | 4 +- headers/libs/alm/Tab.h | 40 ++++++----- src/libs/alm/ALMLayout.cpp | 121 ++++++++++++++++++++--------- src/libs/alm/Area.cpp | 12 ++-- src/libs/alm/Jamfile | 1 + src/libs/alm/RowColumnManager.cpp | 6 +- src/libs/alm/Tab.cpp | 37 +++++++++ src/libs/linprog/ActiveSetSolver.cpp | 68 +++++++++++------ src/libs/linprog/ActiveSetSolver.h | 4 + src/libs/linprog/LayoutOptimizer.cpp | 21 +++++- src/libs/linprog/LayoutOptimizer.h | 3 - src/libs/linprog/LinearSpec.cpp | 11 ++- ############################################################################ Commit: 57014d1ff77c40a32732075f23a322c2ce32a4d7 URL: http://cgit.haiku-os.org/haiku/commit/?id=57014d1 Author: czeidler <haiku@xxxxxxxxxxxxxxxxxx> Date: Wed Nov 30 04:55:36 2011 UTC Make tabs BReferenceable. Maintain a list of tabs. ---------------------------------------------------------------------------- diff --git a/headers/libs/alm/ALMLayout.h b/headers/libs/alm/ALMLayout.h index 5ddba62..e4d771a 100644 --- a/headers/libs/alm/ALMLayout.h +++ b/headers/libs/alm/ALMLayout.h @@ -35,12 +35,16 @@ public: BALMLayout* friendLayout = NULL); virtual ~BALMLayout(); - XTab* AddXTab(); - YTab* AddYTab(); + BReference<XTab> AddXTab(); + BReference<YTab> AddYTab(); + int32 CountXTabs() const; int32 CountYTabs() const; XTab* XTabAt(int32 index) const; YTab* YTabAt(int32 index) const; + /*! Order the tab list and return a reference to the list. */ + const XTabList& OrderedXTabs(); + const YTabList& OrderedYTabs(); Row* AddRow(YTab* top, YTab* bottom); Column* AddColumn(XTab* left, XTab* right); @@ -104,6 +108,7 @@ public: YTab* bottom = NULL); virtual Area* AddItem(BLayoutItem* item, Row* row, Column* column); + virtual Area* AddItemToRight(BLayoutItem* item, XTab* right = NULL, YTab* top = NULL, YTab* bottom = NULL); @@ -129,6 +134,9 @@ public: virtual void DerivedLayoutItems(); private: + friend class XTab; + friend class YTab; + /*! Add a view without initialize the Area. */ BLayoutItem* _CreateLayoutItem(BView* view); @@ -138,16 +146,18 @@ private: BSize _CalculateMaxSize(); BSize _CalculatePreferredSize(); - void _ParseGroupItem(GroupItem& item, XTab* left, - YTab* top, XTab* right, YTab* bottom); + void _ParseGroupItem(GroupItem& item, + BReference<XTab> left, BReference<YTab> top, + BReference<XTab> right, + BReference<YTab> bottom); LinearSpec* fSolver; LinearSpec fOwnSolver; - XTab* fLeft; - XTab* fRight; - YTab* fTop; - YTab* fBottom; + BReference<XTab> fLeft; + BReference<XTab> fRight; + BReference<YTab> fTop; + BReference<YTab> fBottom; BSize fMinSize; BSize fMaxSize; BSize fPreferredSize; diff --git a/headers/libs/alm/Area.h b/headers/libs/alm/Area.h index 535d661..fc49fc6 100644 --- a/headers/libs/alm/Area.h +++ b/headers/libs/alm/Area.h @@ -103,8 +103,8 @@ public: void InvalidateSizeConstraints(); - BRect Frame(); - BRect ItemFrame(); + BRect Frame() const; + BRect ItemFrame() const; private: Area(BLayoutItem* item); @@ -124,10 +124,10 @@ private: LinearSpec* fLS; - XTab* fLeft; - XTab* fRight; - YTab* fTop; - YTab* fBottom; + BReference<XTab> fLeft; + BReference<XTab> fRight; + BReference<YTab> fTop; + BReference<YTab> fBottom; Row* fRow; Column* fColumn; diff --git a/headers/libs/alm/Column.h b/headers/libs/alm/Column.h index 7ffff3a..99a8a40 100644 --- a/headers/libs/alm/Column.h +++ b/headers/libs/alm/Column.h @@ -33,8 +33,8 @@ private: Column(LinearSpec* ls, XTab* left, XTab* right); LinearSpec* fLS; - XTab* fLeft; - XTab* fRight; + BReference<XTab> fLeft; + BReference<XTab> fRight; //! managed by RowColumnManager Constraint* fPrefSizeConstraint; diff --git a/headers/libs/alm/Row.h b/headers/libs/alm/Row.h index caa1b56..09e9728 100644 --- a/headers/libs/alm/Row.h +++ b/headers/libs/alm/Row.h @@ -33,8 +33,8 @@ private: Row(LinearSpec* ls, YTab* top, YTab* bottom); LinearSpec* fLS; - YTab* fTop; - YTab* fBottom; + BReference<YTab> fTop; + BReference<YTab> fBottom; //! managed by RowColumnManager Constraint* fPrefSizeConstraint; diff --git a/headers/libs/alm/Tab.h b/headers/libs/alm/Tab.h index 0c644c7..3110451 100644 --- a/headers/libs/alm/Tab.h +++ b/headers/libs/alm/Tab.h @@ -6,6 +6,7 @@ #define X_TAB_H +#include <Referenceable.h> #include "LinearSpec.h" #include "Variable.h" @@ -13,34 +14,37 @@ namespace BALM { +class BALMLayout; + + /** * Vertical grid line (x-tab). */ -class XTab : public Variable { -protected: - XTab(LinearSpec* ls) - : - Variable(ls) - { - - } - +class XTab : public Variable, public BReferenceable { public: - friend class BALMLayout; -}; + virtual ~XTab(); + friend class BALMLayout; -class YTab : public Variable { protected: - YTab(LinearSpec* ls) - : - Variable(ls) - { - - } + XTab(BALMLayout* layout); +private: + BALMLayout* fALMLayout; +}; + + +class YTab : public Variable, public BReferenceable { public: + virtual ~YTab(); + friend class BALMLayout; + +protected: + YTab(BALMLayout* layout); + +private: + BALMLayout* fALMLayout; }; diff --git a/src/libs/alm/ALMLayout.cpp b/src/libs/alm/ALMLayout.cpp index ebb47b8..bae4fa1 100644 --- a/src/libs/alm/ALMLayout.cpp +++ b/src/libs/alm/ALMLayout.cpp @@ -68,16 +68,14 @@ BALMLayout::~BALMLayout() * * @return the new x-tab */ -XTab* +BReference<XTab> BALMLayout::AddXTab() { - XTab* tab = new(std::nothrow) XTab(fSolver); + BReference<XTab> tab(new(std::nothrow) XTab(this), true); if (!tab) return NULL; - if (!fSolver->AddVariable(tab)) { - delete tab; + if (!fSolver->AddVariable(tab)) return NULL; - } fXTabList.AddItem(tab); return tab; @@ -89,16 +87,14 @@ BALMLayout::AddXTab() * * @return the new y-tab */ -YTab* +BReference<YTab> BALMLayout::AddYTab() { - YTab* tab = new(std::nothrow) YTab(fSolver); - if (!tab) + BReference<YTab> tab(new(std::nothrow) YTab(this), true); + if (tab.Get() == NULL) return NULL; - if (!fSolver->AddVariable(tab)) { - delete tab; + if (!fSolver->AddVariable(tab)) return NULL; - } fYTabList.AddItem(tab); return tab; @@ -133,6 +129,45 @@ BALMLayout::YTabAt(int32 index) const } +int +CompareXTabFunc(const XTab* tab1, const XTab* tab2) +{ + if (tab1->Value() < tab2->Value()) + return -1; + else if (tab1->Value() == tab2->Value()) + return 0; + return 1; +} + + +int +CompareYTabFunc(const YTab* tab1, const YTab* tab2) +{ + if (tab1->Value() < tab2->Value()) + return -1; + else if (tab1->Value() == tab2->Value()) + return 0; + return 1; +} + + + +const XTabList& +BALMLayout::OrderedXTabs() +{ + fXTabList.SortItems(CompareXTabFunc); + return fXTabList; +} + + +const YTabList& +BALMLayout::OrderedYTabs() +{ + fYTabList.SortItems(CompareYTabFunc); + return fYTabList; +} + + /** * Adds a new row to the specification that is glued to the given y-tabs. * @@ -141,11 +176,13 @@ BALMLayout::YTabAt(int32 index) const * @return the new row */ Row* -BALMLayout::AddRow(YTab* top, YTab* bottom) +BALMLayout::AddRow(YTab* _top, YTab* _bottom) { - if (top == NULL) + BReference<YTab> top = _top; + BReference<YTab> bottom = _bottom; + if (_top == NULL) top = AddYTab(); - if (bottom == NULL) + if (_bottom == NULL) bottom = AddYTab(); return new(std::nothrow) Row(fSolver, top, bottom); } @@ -159,11 +196,13 @@ BALMLayout::AddRow(YTab* top, YTab* bottom) * @return the new column */ Column* -BALMLayout::AddColumn(XTab* left, XTab* right) +BALMLayout::AddColumn(XTab* _left, XTab* _right) { - if (left == NULL) + BReference<XTab> left = _left; + BReference<XTab> right = _right; + if (_left == NULL) left = AddXTab(); - if (right == NULL) + if (_right == NULL) right = AddXTab(); return new(std::nothrow) Column(fSolver, left, right); } @@ -319,13 +358,13 @@ void BALMLayout::BuildLayout(GroupItem& item, XTab* left, YTab* top, XTab* right, YTab* bottom) { - if (!left) + if (left == NULL) left = Left(); - if (!top) + if (top == NULL) top = Top(); - if (!right) + if (right == NULL) right = Right(); - if (!bottom) + if (bottom == NULL) bottom = Bottom(); _ParseGroupItem(item, left, top, right, bottom); @@ -333,8 +372,8 @@ BALMLayout::BuildLayout(GroupItem& item, XTab* left, YTab* top, XTab* right, void -BALMLayout::_ParseGroupItem(GroupItem& item, XTab* left, YTab* top, XTab* right, - YTab* bottom) +BALMLayout::_ParseGroupItem(GroupItem& item, BReference<XTab> left, + BReference<YTab> top, BReference<XTab> right, BReference<YTab> bottom) { if (item.LayoutItem()) AddItem(item.LayoutItem(), left, top, right, bottom); @@ -346,14 +385,14 @@ BALMLayout::_ParseGroupItem(GroupItem& item, XTab* left, YTab* top, XTab* right, GroupItem& current = const_cast<GroupItem&>( item.GroupItems()[i]); if (item.Orientation() == B_HORIZONTAL) { - XTab* r = (i == item.GroupItems().size() - 1) ? right + BReference<XTab> r = (i == item.GroupItems().size() - 1) ? right : AddXTab(); _ParseGroupItem(current, left, top, r, bottom); left = r; } else { - YTab* b = (i == item.GroupItems().size() - 1) ? bottom - : AddYTab(); + BReference<YTab> b = (i == item.GroupItems().size() - 1) + ? bottom : AddYTab(); _ParseGroupItem(current, left, top, right, b); top = b; } @@ -510,12 +549,14 @@ BALMLayout::AddItem(int32 index, BLayoutItem* item) Area* -BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* right, - YTab* bottom) +BALMLayout::AddItem(BLayoutItem* item, XTab* left, YTab* top, XTab* _right, + YTab* _bottom) { - if (!right) + BReference<XTab> right = _right; + if (right.Get() == NULL) right = AddXTab(); - if (!bottom) + BReference<YTab> bottom = _bottom; + if (bottom.Get() == NULL) bottom = AddYTab(); // Area is added int ItemAdded @@ -551,14 +592,15 @@ BALMLayout::AddItem(BLayoutItem* item, Row* row, Column* column) Area* -BALMLayout::AddItemToRight(BLayoutItem* item, XTab* right, YTab* top, +BALMLayout::AddItemToRight(BLayoutItem* item, XTab* _right, YTab* top, YTab* bottom) { if (fCurrentArea == NULL) return NULL; XTab* left = fCurrentArea->Right(); - if (!right) + BReference<XTab> right = _right; + if (_right == NULL) right = AddXTab(); if (!top) top = fCurrentArea->Top(); @@ -570,13 +612,14 @@ BALMLayout::AddItemToRight(BLayoutItem* item, XTab* right, YTab* top, Area* -BALMLayout::AddItemToLeft(BLayoutItem* item, XTab* left, YTab* top, +BALMLayout::AddItemToLeft(BLayoutItem* item, XTab* _left, YTab* top, YTab* bottom) { if (fCurrentArea == NULL) return NULL; - if (!left) + BReference<XTab> left = _left; + if (_left == NULL) left = AddXTab(); XTab* right = fCurrentArea->Left(); if (!top) @@ -589,7 +632,7 @@ BALMLayout::AddItemToLeft(BLayoutItem* item, XTab* left, YTab* top, Area* -BALMLayout::AddItemToTop(BLayoutItem* item, YTab* top, XTab* left, XTab* right) +BALMLayout::AddItemToTop(BLayoutItem* item, YTab* _top, XTab* left, XTab* right) { if (fCurrentArea == NULL) return NULL; @@ -598,7 +641,8 @@ BALMLayout::AddItemToTop(BLayoutItem* item, YTab* top, XTab* left, XTab* right) left = fCurrentArea->Left(); if (!right) right = fCurrentArea->Right(); - if (!top) + BReference<YTab> top = _top; + if (_top == NULL) top = AddYTab(); YTab* bottom = fCurrentArea->Top(); @@ -607,7 +651,7 @@ BALMLayout::AddItemToTop(BLayoutItem* item, YTab* top, XTab* left, XTab* right) Area* -BALMLayout::AddItemToBottom(BLayoutItem* item, YTab* bottom, XTab* left, +BALMLayout::AddItemToBottom(BLayoutItem* item, YTab* _bottom, XTab* left, XTab* right) { if (fCurrentArea == NULL) @@ -618,7 +662,8 @@ BALMLayout::AddItemToBottom(BLayoutItem* item, YTab* bottom, XTab* left, if (!right) right = fCurrentArea->Right(); YTab* top = fCurrentArea->Bottom(); - if (!bottom) + BReference<YTab> bottom = _bottom; + if (_bottom == NULL) bottom = AddYTab(); return AddItem(item, left, top, right, bottom); diff --git a/src/libs/alm/Area.cpp b/src/libs/alm/Area.cpp index f2b22db..a255a7d 100644 --- a/src/libs/alm/Area.cpp +++ b/src/libs/alm/Area.cpp @@ -337,7 +337,7 @@ Area::LeftInset() const return fTopLeftInset.Width(); BALMLayout* layout = static_cast<BALMLayout*>(fLayoutItem->Layout()); - if (fLeft == layout->Left()) + if (fLeft.Get() == layout->Left()) return layout->Inset(); return layout->Spacing() / 2; } @@ -353,7 +353,7 @@ Area::TopInset() const return fTopLeftInset.Height(); BALMLayout* layout = static_cast<BALMLayout*>(fLayoutItem->Layout()); - if (fTop == layout->Top()) + if (fTop.Get() == layout->Top()) return layout->Inset(); return layout->Spacing() / 2; } @@ -369,7 +369,7 @@ Area::RightInset() const return fRightBottomInset.Width(); BALMLayout* layout = static_cast<BALMLayout*>(fLayoutItem->Layout()); - if (fRight == layout->Right()) + if (fRight.Get() == layout->Right()) return layout->Inset(); return layout->Spacing() / 2; } @@ -385,7 +385,7 @@ Area::BottomInset() const return fRightBottomInset.Height(); BALMLayout* layout = static_cast<BALMLayout*>(fLayoutItem->Layout()); - if (fBottom == layout->Bottom()) + if (fBottom.Get() == layout->Bottom()) return layout->Inset(); return layout->Spacing() / 2; } @@ -497,7 +497,7 @@ Area::InvalidateSizeConstraints() BRect -Area::Frame() +Area::Frame() const { return BRect(fLeft->Value(), fTop->Value(), fRight->Value(), fBottom->Value()); @@ -505,7 +505,7 @@ Area::Frame() BRect -Area::ItemFrame() +Area::ItemFrame() const { return fLayoutItem->Frame(); } diff --git a/src/libs/alm/Jamfile b/src/libs/alm/Jamfile index 1fb518b..906cedd 100644 --- a/src/libs/alm/Jamfile +++ b/src/libs/alm/Jamfile @@ -12,6 +12,7 @@ SharedLibrary libalm.so : Column.cpp Row.cpp RowColumnManager.cpp + Tab.cpp : liblpsolve55.so liblinprog.a be $(TARGET_LIBSTDC++) diff --git a/src/libs/alm/RowColumnManager.cpp b/src/libs/alm/RowColumnManager.cpp index 20da2cd..f7593eb 100644 --- a/src/libs/alm/RowColumnManager.cpp +++ b/src/libs/alm/RowColumnManager.cpp @@ -108,7 +108,8 @@ RowColumnManager::_FindRowFor(Area* area) { for (int32 i = 0; i < fRows.CountItems(); i++) { Row* row = fRows.ItemAt(i); - if (row->fTop == area->Top() && row->fBottom == area->Bottom()) + if (row->fTop.Get() == area->Top() + && row->fBottom.Get() == area->Bottom()) return row; } return NULL; @@ -120,7 +121,8 @@ RowColumnManager::_FindColumnFor(Area* area) { for (int32 i = 0; i < fColumns.CountItems(); i++) { Column* column = fColumns.ItemAt(i); - if (column->fLeft == area->Left() && column->fRight == area->Right()) + if (column->fLeft.Get() == area->Left() + && column->fRight.Get() == area->Right()) return column; } return NULL; diff --git a/src/libs/alm/Tab.cpp b/src/libs/alm/Tab.cpp new file mode 100644 index 0000000..a116bcb --- /dev/null +++ b/src/libs/alm/Tab.cpp @@ -0,0 +1,37 @@ +/* + * Copyright 2011, Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx> + * Distributed under the terms of the MIT License. + */ + + +#include <Tab.h> + +#include <ALMLayout.h> + + +XTab::XTab(BALMLayout* layout) + : + Variable(layout->Solver()), + fALMLayout(layout) +{ +} + + +XTab::~XTab() +{ + fALMLayout->fXTabList.RemoveItem(this); +} + + +YTab::YTab(BALMLayout* layout) + : + Variable(layout->Solver()), + fALMLayout(layout) +{ +} + + +YTab::~YTab() +{ + fALMLayout->fYTabList.RemoveItem(this); +} ############################################################################ Revision: hrev43369 Commit: 056207eedd7703fb5d2941ef2a007c883deaab25 URL: http://cgit.haiku-os.org/haiku/commit/?id=056207e Author: czeidler <haiku@xxxxxxxxxxxxxxxxxx> Date: Wed Nov 30 05:22:39 2011 UTC Cleanup the constraint solver a bit and fix a bug when a variable is removed. ---------------------------------------------------------------------------- diff --git a/src/libs/linprog/ActiveSetSolver.cpp b/src/libs/linprog/ActiveSetSolver.cpp index 895dcaf..0948c39 100644 --- a/src/libs/linprog/ActiveSetSolver.cpp +++ b/src/libs/linprog/ActiveSetSolver.cpp @@ -125,7 +125,7 @@ EquationSystem::SwapRow(int32 i, int32 j) bool -EquationSystem::GaussJordan() +EquationSystem::GaussianElimination() { // basic solve for (int i = 0; i < fRows; i++) { @@ -158,34 +158,29 @@ EquationSystem::GaussJordan() SwapRow(i, swapRow); // normalize - GaussJordan(i); + _EliminateColumn(i, i + 1, fRows - 1); } return true; } -void -EquationSystem::GaussJordan(int32 i) +bool +EquationSystem::GaussJordan() { - double value = fMatrix[fRowIndices[i]][fColumnIndices[i]]; - for (int j = 0; j < fColumns; j++) - fMatrix[fRowIndices[i]][fColumnIndices[j]] /= value; - fB[i] /= value; + if (!GaussianElimination()) + return false; - for (int r = 0; r < fRows; r++) { - if (r == i) - continue; - double q = -fMatrix[fRowIndices[r]][fColumnIndices[i]]; - // don't need to do nothing, since matrix is typically sparse this - // should save some work - if (fuzzy_equals(q, 0)) - continue; - for (int c = 0; c < fColumns; c++) - fMatrix[fRowIndices[r]][fColumnIndices[c]] - += fMatrix[fRowIndices[i]][fColumnIndices[c]] * q; + for (int32 i = fRows - 1; i >= 0; i--) + _EliminateColumn(i, 0, i - 1); - fB[r] += fB[i] * q; - } + return true; +} + + +void +EquationSystem::GaussJordan(int32 i) +{ + _EliminateColumn(i, 0, fRows - 1); } @@ -271,6 +266,33 @@ EquationSystem::Print() } +void +EquationSystem::_EliminateColumn(int32 column, int32 startRow, int32 endRow) +{ + double value = fMatrix[fRowIndices[column]][fColumnIndices[column]]; + if (value != 1.) { + for (int j = column; j < fColumns; j++) + fMatrix[fRowIndices[column]][fColumnIndices[j]] /= value; + fB[column] /= value; + } + + for (int r = startRow; r < endRow + 1; r++) { + if (r == column) + continue; + double q = -fMatrix[fRowIndices[r]][fColumnIndices[column]]; + // don't need to do anything, since matrix is typically sparse this + // should save some work + if (fuzzy_equals(q, 0)) + continue; + for (int c = column; c < fColumns; c++) + fMatrix[fRowIndices[r]][fColumnIndices[c]] + += fMatrix[fRowIndices[column]][fColumnIndices[c]] * q; + + fB[r] += fB[column] * q; + } +} + + ActiveSetSolver::ActiveSetSolver(LinearSpec* linearSpec) : QPSolverInterface(linearSpec), @@ -293,7 +315,7 @@ Solving Inequalities and Proving Farkas's Lemma Made Easy David Avis and Bohdan Kaluzny The American Mathematical Monthly Vol. 111, No. 2 (Feb., 2004), pp. 152-157 */ -bool +static bool solve(EquationSystem& system) { // basic solve @@ -392,7 +414,7 @@ ActiveSetSolver::Solve() double results[nVariables + nConstraints]; system.Results(results, nVariables + nConstraints); - printf("base system solved\n"); + TRACE("base system solved\n"); LayoutOptimizer optimizer(fConstraints, nVariables); optimizer.Solve(results); diff --git a/src/libs/linprog/ActiveSetSolver.h b/src/libs/linprog/ActiveSetSolver.h index 2a137c2..2bd453a 100644 --- a/src/libs/linprog/ActiveSetSolver.h +++ b/src/libs/linprog/ActiveSetSolver.h @@ -27,6 +27,7 @@ public: inline void SwapColumn(int32 i, int32 j); inline void SwapRow(int32 i, int32 j); + bool GaussianElimination(); bool GaussJordan(); /*! Gauss Jordan elimination just for one column, the diagonal element must be none zero. */ @@ -39,6 +40,9 @@ public: void Print(); private: + inline void _EliminateColumn(int32 column, int32 startRow, + int32 endRow); + int32* fRowIndices; int32* fColumnIndices; double** fMatrix; diff --git a/src/libs/linprog/LayoutOptimizer.cpp b/src/libs/linprog/LayoutOptimizer.cpp index 15289a3..b51ad2f 100644 --- a/src/libs/linprog/LayoutOptimizer.cpp +++ b/src/libs/linprog/LayoutOptimizer.cpp @@ -259,8 +259,21 @@ swap(Type& a, Type& b) // #pragma mark - algorithms +#if 0 +static void +print_system(double** a, int n, double* b) +{ + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + printf("%.1f ", a[i][j]); + } + printf("= %f\n", b[i]); + } +} +#endif -bool + +static bool solve(double** a, int n, double* b) { // index array for row permutation @@ -312,6 +325,8 @@ solve(double** a, int n, double* b) for (int j = i + 1; j < n; j++) sum -= a[index][j] * b[j]; + if (fuzzy_equals(a[index][i], 0)) + return false; b[i] = sum / a[index][i]; } @@ -382,7 +397,7 @@ compute_dependencies(double** a, int m, int n, // remove_linearly_dependent_rows -int +static int remove_linearly_dependent_rows(double** A, double** temp, bool* independentRows, int m, int n) { @@ -411,7 +426,7 @@ remove_linearly_dependent_rows(double** A, double** temp, /*! QR decomposition using Householder transformations. */ -bool +static bool qr_decomposition(double** a, int m, int n, double* d, double** q) { if (m < n) diff --git a/src/libs/linprog/LayoutOptimizer.h b/src/libs/linprog/LayoutOptimizer.h index 82e8966..b77e96a 100644 --- a/src/libs/linprog/LayoutOptimizer.h +++ b/src/libs/linprog/LayoutOptimizer.h @@ -19,9 +19,6 @@ void free_matrix(double** matrix); void copy_matrix(const double* const* A, double** B, int m, int n); void zero_matrix(double** A, int m, int n); int compute_dependencies(double** a, int m, int n, bool* independent); -int remove_linearly_dependent_rows(double** A, double** temp, - bool* independentRows, int m, int n); -bool solve(double** a, int n, double* b); class LayoutOptimizer { diff --git a/src/libs/linprog/LinearSpec.cpp b/src/libs/linprog/LinearSpec.cpp index 4117704..e9f40fe 100644 --- a/src/libs/linprog/LinearSpec.cpp +++ b/src/libs/linprog/LinearSpec.cpp @@ -112,14 +112,15 @@ LinearSpec::AddVariable(Variable* variable) bool LinearSpec::RemoveVariable(Variable* variable, bool deleteVariable) { - // do we know the variable? - if (fVariables.RemoveItem(variable) == false) - return false; - // must be called first otherwise the index is invalid if (fSolver->VariableRemoved(variable) == false) return false; + // do we know the variable? + if (fVariables.RemoveItem(variable) == false) + return false; + fUsedVariables.RemoveItem(variable); + variable->fIsValid = false; // invalidate all constraints that use this variable @@ -141,7 +142,7 @@ LinearSpec::RemoveVariable(Variable* variable, bool deleteVariable) } } for (int i = 0; i < markedForInvalidation.CountItems(); i++) - markedForInvalidation.ItemAt(i)->Invalidate(); + RemoveConstraint(markedForInvalidation.ItemAt(i)); if (deleteVariable)