@@ -5,18 +5,47 @@ module Linear.Simplex.Solver.TwoPhaseSpec where
55
66import Prelude hiding (EQ )
77
8- import Control.Monad.Logger
8+ import Control.Monad.Logger ( LogLevel ( LevelInfo ), filterLogger , runStdoutLoggingT )
99import qualified Data.Map as M
1010import Data.Maybe (isJust )
11- import Data.Ratio
11+ import Data.Ratio ( (%) )
1212import qualified Data.Set as Set
1313
14- import Test.Hspec
15- import Test.QuickCheck
14+ import Test.Hspec ( Spec , describe , expectationFailure , it , shouldBe , shouldSatisfy )
15+ import Test.QuickCheck ( NonEmptyList ( .. ), Positive ( .. ), property , (==>) )
1616
17- import Linear.Simplex.Prettify
17+ import Linear.Simplex.Prettify ( prettyShowObjectiveFunction , prettyShowPolyConstraint , prettyShowVarLitMapSum )
1818import Linear.Simplex.Solver.TwoPhase
19+ ( applyShiftToConstraint
20+ , applyShiftToObjective
21+ , applySplitToConstraint
22+ , applySplitToObjective
23+ , applyTransform
24+ , applyTransforms
25+ , collectAllVars
26+ , computeObjective
27+ , generateTransform
28+ , getTransform
29+ , postprocess
30+ , preprocess
31+ , twoPhaseSimplex
32+ , unapplyTransformToVarMap
33+ , unapplyTransformsToVarMap
34+ )
1935import Linear.Simplex.Types
36+ ( ObjectiveFunction (.. )
37+ , ObjectiveResult (.. )
38+ , OptimisationOutcome (.. )
39+ , PolyConstraint (.. )
40+ , SimplexResult (.. )
41+ , VarDomainMap (.. )
42+ , VarTransform (.. )
43+ , boundedRange
44+ , lowerBoundOnly
45+ , nonNegative
46+ , unbounded
47+ , upperBoundOnly
48+ )
2049
2150spec :: Spec
2251spec = do
@@ -2662,47 +2691,52 @@ spec = do
26622691 it " RHS adjustment follows formula: newRHS = oldRHS - coeff * shiftBy" $
26632692 property $
26642693 \ (coeff :: Rational ) (oldRHS :: Rational ) (shiftBy :: Rational ) ->
2665- coeff /= 0 ==>
2666- let constraint = LEQ (M. fromList [(1 , coeff)]) oldRHS
2667- LEQ _ newRHS = applyShiftToConstraint 1 10 shiftBy constraint
2668- in newRHS == oldRHS - coeff * shiftBy
2694+ coeff
2695+ /= 0
2696+ ==> let constraint = LEQ (M. fromList [(1 , coeff)]) oldRHS
2697+ LEQ _ newRHS = applyShiftToConstraint 1 10 shiftBy constraint
2698+ in newRHS == oldRHS - coeff * shiftBy
26692699
26702700 it " preserves constraint type (LEQ stays LEQ)" $
26712701 property $
26722702 \ (coeff :: Rational ) (rhs :: Rational ) (shiftBy :: Rational ) ->
2673- coeff /= 0 ==>
2674- let constraint = LEQ (M. fromList [(1 , coeff)]) rhs
2675- in case applyShiftToConstraint 1 10 shiftBy constraint of
2676- LEQ {} -> True
2677- _ -> False
2703+ coeff
2704+ /= 0
2705+ ==> let constraint = LEQ (M. fromList [(1 , coeff)]) rhs
2706+ in case applyShiftToConstraint 1 10 shiftBy constraint of
2707+ LEQ {} -> True
2708+ _ -> False
26782709
26792710 it " preserves constraint type (GEQ stays GEQ)" $
26802711 property $
26812712 \ (coeff :: Rational ) (rhs :: Rational ) (shiftBy :: Rational ) ->
2682- coeff /= 0 ==>
2683- let constraint = GEQ (M. fromList [(1 , coeff)]) rhs
2684- in case applyShiftToConstraint 1 10 shiftBy constraint of
2685- GEQ {} -> True
2686- _ -> False
2713+ coeff
2714+ /= 0
2715+ ==> let constraint = GEQ (M. fromList [(1 , coeff)]) rhs
2716+ in case applyShiftToConstraint 1 10 shiftBy constraint of
2717+ GEQ {} -> True
2718+ _ -> False
26872719
26882720 describe " applySplitToConstraint properties" $ do
26892721 it " preserves RHS value" $
26902722 property $
26912723 \ (coeff :: Rational ) (rhs :: Rational ) ->
2692- coeff /= 0 ==>
2693- let constraint = LEQ (M. fromList [(1 , coeff)]) rhs
2694- LEQ _ newRHS = applySplitToConstraint 1 10 11 constraint
2695- in newRHS == rhs
2724+ coeff
2725+ /= 0
2726+ ==> let constraint = LEQ (M. fromList [(1 , coeff)]) rhs
2727+ LEQ _ newRHS = applySplitToConstraint 1 10 11 constraint
2728+ in newRHS == rhs
26962729
26972730 it " negVar coefficient is negation of posVar coefficient" $
26982731 property $
26992732 \ (coeff :: Rational ) (rhs :: Rational ) ->
2700- coeff /= 0 ==>
2701- let constraint = LEQ (M. fromList [(1 , coeff)]) rhs
2702- LEQ m _ = applySplitToConstraint 1 10 11 constraint
2703- posCoeff = M. findWithDefault 0 10 m
2704- negCoeff = M. findWithDefault 0 11 m
2705- in negCoeff == negate posCoeff
2733+ coeff
2734+ /= 0
2735+ ==> let constraint = LEQ (M. fromList [(1 , coeff)]) rhs
2736+ LEQ m _ = applySplitToConstraint 1 10 11 constraint
2737+ posCoeff = M. findWithDefault 0 10 m
2738+ negCoeff = M. findWithDefault 0 11 m
2739+ in negCoeff == negate posCoeff
27062740
27072741 describe " unapplyTransformToVarMap Shift properties" $ do
27082742 it " recovers originalVar = shiftedVar + shiftBy" $
@@ -2743,12 +2777,14 @@ spec = do
27432777 it " Shift transform and unapply is identity for variable value" $
27442778 property $
27452779 \ (origVal :: Rational ) (shiftBy :: Rational ) ->
2746- shiftBy < 0 ==> -- Only negative shifts are valid
2747- let shiftedVal = origVal - shiftBy -- shiftedVar = originalVar - shiftBy
2748- varMap = M. fromList [(5 , 100 ), (10 , shiftedVal)]
2749- transform = Shift 1 10 shiftBy
2750- newVarMap = unapplyTransformToVarMap transform varMap
2751- in M. lookup 1 newVarMap == Just origVal
2780+ shiftBy
2781+ < 0
2782+ ==> let shiftedVal -- Only negative shifts are valid
2783+ = origVal - shiftBy -- shiftedVar = originalVar - shiftBy
2784+ varMap = M. fromList [(5 , 100 ), (10 , shiftedVal)]
2785+ transform = Shift 1 10 shiftBy
2786+ newVarMap = unapplyTransformToVarMap transform varMap
2787+ in M. lookup 1 newVarMap == Just origVal
27522788
27532789 it " Split with posVal=origVal and negVal=0 gives correct value for positive origVal" $
27542790 property $
0 commit comments