Author: czeidler Date: 2011-01-26 23:06:02 +0100 (Wed, 26 Jan 2011) New Revision: 40297 Changeset: http://dev.haiku-os.org/changeset/40297 Modified: haiku/trunk/headers/libs/linprog/LinearSpec.h haiku/trunk/headers/libs/linprog/Variable.h haiku/trunk/src/libs/alm/Area.cpp haiku/trunk/src/libs/linprog/ActiveSetSolver.cpp haiku/trunk/src/libs/linprog/ActiveSetSolver.h haiku/trunk/src/libs/linprog/LayoutOptimizer.cpp haiku/trunk/src/libs/linprog/LinearSpec.cpp haiku/trunk/src/libs/linprog/Variable.cpp Log: Fix min/ max calculation by removing all soft constraints before doing so. Smaller fixes. Modified: haiku/trunk/headers/libs/linprog/LinearSpec.h =================================================================== --- haiku/trunk/headers/libs/linprog/LinearSpec.h 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/headers/libs/linprog/LinearSpec.h 2011-01-26 22:06:02 UTC (rev 40297) @@ -148,6 +148,7 @@ double penaltyNeg, double penaltyPos); VariableList fVariables; + VariableList fUsedVariables; ConstraintList fConstraints; ResultType fResult; bigtime_t fSolvingTime; Modified: haiku/trunk/headers/libs/linprog/Variable.h =================================================================== --- haiku/trunk/headers/libs/linprog/Variable.h 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/headers/libs/linprog/Variable.h 2011-01-26 22:06:02 UTC (rev 40297) @@ -58,6 +58,9 @@ protected: Variable(LinearSpec* ls); + //! returns the ref count + int32 AddReference(); + int32 RemoveReference(); private: LinearSpec* fLS; @@ -68,6 +71,7 @@ bool fIsValid; + int32 fReferenceCount; public: friend class LinearSpec; }; Modified: haiku/trunk/src/libs/alm/Area.cpp =================================================================== --- haiku/trunk/src/libs/alm/Area.cpp 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/src/libs/alm/Area.cpp 2011-01-26 22:06:02 UTC (rev 40297) @@ -635,15 +635,16 @@ fScaleHeight, kEQ, 0, fShrinkPenalties.Height(), fGrowPenalties.Height()); #else - BSize preferredSize = fLayoutItem->PreferredSize(); fPreferredContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, kEQ, 0, fShrinkPenalties.Width(), fGrowPenalties.Width()); - _UpdatePreferredWidthConstraint(preferredSize); fPreferredContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, kEQ, 0, fShrinkPenalties.Height(), fGrowPenalties.Height()); - _UpdatePreferredHeightConstraint(preferredSize); #endif + BSize preferredSize = fLayoutItem->PreferredSize(); + _UpdatePreferredWidthConstraint(preferredSize); + _UpdatePreferredHeightConstraint(preferredSize); + fConstraints.AddItem(fPreferredContentWidth); fConstraints.AddItem(fPreferredContentHeight); } Modified: haiku/trunk/src/libs/linprog/ActiveSetSolver.cpp =================================================================== --- haiku/trunk/src/libs/linprog/ActiveSetSolver.cpp 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/src/libs/linprog/ActiveSetSolver.cpp 2011-01-26 22:06:02 UTC (rev 40297) @@ -504,6 +504,9 @@ BSize ActiveSetSolver::MinSize(Variable* width, Variable* height) { + ConstraintList softConstraints; + _RemoveSoftConstraint(softConstraints); + Constraint* heightConstraint = fLinearSpec->AddConstraint(1, height, kEQ, 0, 5, 5); Constraint* widthConstraint = fLinearSpec->AddConstraint(1, width, @@ -512,6 +515,8 @@ fLinearSpec->RemoveConstraint(heightConstraint); fLinearSpec->RemoveConstraint(widthConstraint); + _AddSoftConstraint(softConstraints); + if (result == kUnbounded) return kMinSize; if (result != kOptimal) @@ -524,6 +529,9 @@ BSize ActiveSetSolver::MaxSize(Variable* width, Variable* height) { + ConstraintList softConstraints; + _RemoveSoftConstraint(softConstraints); + const double kHugeValue = 32000; Constraint* heightConstraint = fLinearSpec->AddConstraint(1, height, kEQ, kHugeValue, 5, 5); @@ -533,10 +541,40 @@ fLinearSpec->RemoveConstraint(heightConstraint); fLinearSpec->RemoveConstraint(widthConstraint); + _AddSoftConstraint(softConstraints); + if (result == kUnbounded) - return kMinSize; + return kMaxSize; if (result != kOptimal) printf("Could not solve the layout specification (%d). ", result); return BSize(width->Value(), height->Value()); } + + +void +ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list) +{ + ConstraintList allConstraints = fLinearSpec->Constraints(); + for (int i = 0; i < allConstraints.CountItems(); i++) { + Constraint* constraint = allConstraints.ItemAt(i); + if (!constraint->IsSoft()) + continue; + + if (fLinearSpec->RemoveConstraint(constraint, false) == true) + list.AddItem(constraint); + } +} + + +void +ActiveSetSolver::_AddSoftConstraint(const ConstraintList& list) +{ + for (int i = 0; i < list.CountItems(); i++) { + Constraint* constraint = list.ItemAt(i); + // at least don't leak it + if (fLinearSpec->AddConstraint(constraint) == false) + delete constraint; + } +} + Modified: haiku/trunk/src/libs/linprog/ActiveSetSolver.h =================================================================== --- haiku/trunk/src/libs/linprog/ActiveSetSolver.h 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/src/libs/linprog/ActiveSetSolver.h 2011-01-26 22:06:02 UTC (rev 40297) @@ -71,6 +71,9 @@ BSize MaxSize(Variable* width, Variable* height); public: + void _RemoveSoftConstraint(ConstraintList& list); + void _AddSoftConstraint(const ConstraintList& list); + const VariableList& fVariables; const ConstraintList& fConstraints; Modified: haiku/trunk/src/libs/linprog/LayoutOptimizer.cpp =================================================================== --- haiku/trunk/src/libs/linprog/LayoutOptimizer.cpp 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/src/libs/linprog/LayoutOptimizer.cpp 2011-01-26 22:06:02 UTC (rev 40297) @@ -914,7 +914,6 @@ negate_vector(pz, zn); // fTemp2 = Ztrans * G * Z - //multiply_optimization_matrix_matrix(Z, an, zn, fTemp1); multiply_matrices(fG, Z, fTemp1, zm, fVariableCount, zn); multiply_matrices(fZtrans, fTemp1, fTemp2, zn, zm, zn); Modified: haiku/trunk/src/libs/linprog/LinearSpec.cpp =================================================================== --- haiku/trunk/src/libs/linprog/LinearSpec.cpp 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/src/libs/linprog/LinearSpec.cpp 2011-01-26 22:06:02 UTC (rev 40297) @@ -149,7 +149,7 @@ int32 LinearSpec::IndexOf(const Variable* variable) const { - return fVariables.IndexOf(variable); + return fUsedVariables.IndexOf(variable); } @@ -168,10 +168,20 @@ if (!fConstraints.AddItem(constraint)) return false; + // ref count the used variables + SummandList* leftSide = constraint->LeftSide(); + for (int i = 0; i < leftSide->CountItems(); i++) { + Variable* var = leftSide->ItemAt(i)->Var(); + if (var->AddReference() == 1) + fUsedVariables.AddItem(var); + } + if (!fSolver->ConstraintAdded(constraint)) { - fConstraints.RemoveItem(constraint); + RemoveConstraint(constraint, false); return false; } + + constraint->fIsValid = true; return true; } @@ -183,6 +193,13 @@ fConstraints.RemoveItem(constraint); constraint->fIsValid = false; + SummandList* leftSide = constraint->LeftSide(); + for (int i = 0; i < leftSide->CountItems(); i++) { + Variable* var = leftSide->ItemAt(i)->Var(); + if (var->RemoveReference() == 0) + fUsedVariables.RemoveItem(var); + } + if (deleteConstraint) delete constraint; return true; @@ -559,7 +576,7 @@ const VariableList& LinearSpec::Variables() const { - return fVariables; + return fUsedVariables; } Modified: haiku/trunk/src/libs/linprog/Variable.cpp =================================================================== --- haiku/trunk/src/libs/linprog/Variable.cpp 2011-01-26 21:50:39 UTC (rev 40296) +++ haiku/trunk/src/libs/linprog/Variable.cpp 2011-01-26 22:06:02 UTC (rev 40297) @@ -295,12 +295,29 @@ fMin(-20000), fMax(20000), fLabel(NULL), - fIsValid(false) + fIsValid(false), + fReferenceCount(0) { } +int32 +Variable::AddReference() +{ + fReferenceCount++; + return fReferenceCount; +} + + +int32 +Variable::RemoveReference() +{ + fReferenceCount--; + return fReferenceCount; +} + + /** * Destructor. * Removes the variable from its specification.