From 894d8953a109bc4c20411ea455a542ed09cfd4b0 Mon Sep 17 00:00:00 2001 From: Junaid Rasheed Date: Fri, 2 Oct 2026 11:34:58 +0100 Subject: [PATCH 1/2] refactor(simplex): use standard map selection operations --- src/Linear/Simplex/Solver/TwoPhase.hs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Linear/Simplex/Solver/TwoPhase.hs b/src/Linear/Simplex/Solver/TwoPhase.hs index ca148f0..b93bace 100644 --- a/src/Linear/Simplex/Solver/TwoPhase.hs +++ b/src/Linear/Simplex/Solver/TwoPhase.hs @@ -107,7 +107,7 @@ findFeasibleSolution unsimplifiedSystem = do M.map ( \DictValue {..} -> DictValue - { varMapSum = M.filterWithKey (\k _ -> k `notElem` artificialVars) varMapSum + { varMapSum = M.withoutKeys varMapSum artificialVarSet , .. } ) @@ -194,6 +194,8 @@ findFeasibleSolution unsimplifiedSystem = do (systemWithBasicVars, artificialVars) = systemWithArtificialVars systemWithSlackVars maxVarWithSlackVars + artificialVarSet = Set.fromList artificialVars + finalMaxVar = if null artificialVars then maxVarWithSlackVars else maximum artificialVars systemWithBasicVarsAsDictionary = tableauInDictionaryForm systemWithBasicVars @@ -289,14 +291,14 @@ findFeasibleSolution unsimplifiedSystem = do } where -- Filter out non-artificial entries - rowsToAdd = M.filterWithKey (\k _ -> k `elem` artificialVars) rows - negatedRows = M.map (\(DictValue rowVarMapSum rowConstant) -> DictValue (M.map negate rowVarMapSum) (negate rowConstant)) rowsToAdd + artificialVarSet = Set.fromList artificialVars + rowsToAdd = M.restrictKeys rows artificialVarSet -- Negate rows, discard keys and artificial vars since the pivot objective does not care about them negatedRowsWithoutArtificialVars = map ( \(_, DictValue {..}) -> DictValue - { varMapSum = M.map negate $ M.filterWithKey (\k _ -> k `notElem` artificialVars) varMapSum + { varMapSum = M.map negate $ M.withoutKeys varMapSum artificialVarSet , constant = negate constant } ) @@ -498,7 +500,7 @@ postprocess originalVars transforms (Optimal varVals) = let -- Unapply transforms to get variable values in original space unappliedVarVals = unapplyTransformsToVarMap transforms varVals -- Filter to only include original decision variables - filteredVarVals = M.filterWithKey (\k _ -> Set.member k originalVars) unappliedVarVals + filteredVarVals = M.restrictKeys unappliedVarVals originalVars in Optimal filteredVarVals -- | Compute the value of an objective function given variable values. @@ -885,4 +887,4 @@ simplexPivot objective@(PivotObjective {variable = objectiveVar, function = obje (error "pivot: Basic variable not found in Dict") $ M.lookup leavingVariable dict - filterOutEnteringVarTerm = M.filterWithKey (\vName _ -> vName /= enteringVariable) + filterOutEnteringVarTerm = M.delete enteringVariable From ba8261b81f99859fa4eac3c80db4752c91f8f794 Mon Sep 17 00:00:00 2001 From: Junaid Rasheed Date: Fri, 2 Oct 2026 11:46:26 +0100 Subject: [PATCH 2/2] docs(changelog): document changes in PR #20 --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index d47e0a4..5a15424 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,6 +2,7 @@ ## Unreleased changes +- Use standard Data.Map selection and deletion operations for solver variable filtering. ([#20](https://github.com/rasheedja/simplex-method/pull/20)) - `twoPhaseSimplex` now takes a `VarDomainMap` as its first argument - Specify each variable's domain using smart constructors: `nonNegative`, `unbounded`, `lowerBoundOnly`, `upperBoundOnly`, or `boundedRange` - Variables not in the `VarDomainMap` are assumed to be `unbounded`