Skip to content

Commit d1f2fc6

Browse files
committed
Test Bounds
+ Fix bug with mergeBounds
1 parent 8a9e15b commit d1f2fc6

2 files changed

Lines changed: 171 additions & 2 deletions

File tree

src/Linear/Simplex/Types.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,23 @@ deriveBounds = foldr updateBounds M.empty
371371
updateBounds _ = id
372372

373373
mergeBounds :: Bounds -> Bounds -> Bounds
374-
mergeBounds (Bounds l1 u1) (Bounds l2 u2) = Bounds (liftA2 max l1 l2) (liftA2 min u1 u2)
374+
mergeBounds (Bounds l1 u1) (Bounds l2 u2) = Bounds (mergeLower l1 l2) (mergeUpper u1 u2)
375+
where
376+
mergeLower Nothing b = b
377+
mergeLower a Nothing = a
378+
mergeLower (Just a) (Just b) = Just (max a b)
379+
380+
mergeUpper Nothing b = b
381+
mergeUpper a Nothing = a
382+
mergeUpper (Just a) (Just b) = Just (min a b)
383+
384+
validateBounds :: VarBounds -> Bool
385+
validateBounds boundsMap = all soundBounds $ M.toList boundsMap
386+
where
387+
soundBounds (_, Bounds lowerBound upperBound) =
388+
case (lowerBound, upperBound) of
389+
(Just l, Just u) -> l <= u
390+
(_, _) -> True
375391

376392
-- Eliminate inequalities which are outside the bounds
377393
-- precondition: no zero coefficients

test/Linear/Simplex/TypesSpec.hs

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,4 +538,157 @@ spec = do
538538
<> "\nsimplifiedSimpleSystemEval: "
539539
<> show simplifiedSimpleSystemEval
540540
) $
541-
simpleSystemEval == simplifiedSimpleSystemEval
541+
simpleSystemEval == simplifiedSimpleSystemEval
542+
describe "Bounds" $ do
543+
it "validateBounds finds that deriving bounds for a system where -1 <= x <= 1 has valid bounds" $ do
544+
let simpleSystem =
545+
[ Expr (VarTerm 0) :>= (-1)
546+
, Expr (VarTerm 0) :<= 1
547+
]
548+
derivedBounds = deriveBounds simpleSystem
549+
expectedBounds = Map.fromList [(0, Bounds (Just (-1)) (Just 1))]
550+
derivedBounds `shouldBe` expectedBounds
551+
validateBounds derivedBounds `shouldBe` True
552+
it "validateBounds finds that deriving bounds for a system where 0 <= x <= 1 has valid bounds" $ do
553+
let simpleSystem =
554+
[ Expr (VarTerm 0) :>= 0
555+
, Expr (VarTerm 0) :<= 1
556+
]
557+
derivedBounds = deriveBounds simpleSystem
558+
expectedBounds = Map.fromList [(0, Bounds (Just 0) (Just 1))]
559+
derivedBounds `shouldBe` expectedBounds
560+
validateBounds derivedBounds `shouldBe` True
561+
it "validateBounds finds that deriving bounds for a system where 1 <= x <= 1 has valid bounds" $ do
562+
let simpleSystem =
563+
[ Expr (VarTerm 0) :>= 1
564+
, Expr (VarTerm 0) :<= 1
565+
]
566+
derivedBounds = deriveBounds simpleSystem
567+
expectedBounds = Map.fromList [(0, Bounds (Just 1) (Just 1))]
568+
derivedBounds `shouldBe` expectedBounds
569+
validateBounds derivedBounds `shouldBe` True
570+
it "validateBounds finds that deriving bounds for a system where 1 <= x <= 0 has invalid bounds" $ do
571+
let simpleSystem =
572+
[ Expr (VarTerm 0) :>= 1
573+
, Expr (VarTerm 0) :<= 0
574+
]
575+
derivedBounds = deriveBounds simpleSystem
576+
expectedBounds = Map.fromList [(0, Bounds (Just 1) (Just 0))]
577+
derivedBounds `shouldBe` expectedBounds
578+
validateBounds derivedBounds `shouldBe` False
579+
it "validateBounds finds that deriving bounds for a system where 0 <= x <= 1 and 1 <= y <= 3 has valid bounds" $ do
580+
let simpleSystem =
581+
[ Expr (VarTerm 0) :>= 0
582+
, Expr (VarTerm 0) :<= 1
583+
, Expr (VarTerm 1) :>= 1
584+
, Expr (VarTerm 1) :<= 3
585+
]
586+
derivedBounds = deriveBounds simpleSystem
587+
expectedBounds = Map.fromList [(0, Bounds (Just 0) (Just 1)), (1, Bounds (Just 1) (Just 3))]
588+
derivedBounds `shouldBe` expectedBounds
589+
validateBounds derivedBounds `shouldBe` True
590+
it "validateBounds finds that deriving bounds for a system where 1 <= x <= 0 and 3 <= y <= 1 has invalid bounds" $ do
591+
let simpleSystem =
592+
[ Expr (VarTerm 0) :>= 1
593+
, Expr (VarTerm 0) :<= 0
594+
, Expr (VarTerm 1) :>= 3
595+
, Expr (VarTerm 1) :<= 1
596+
]
597+
derivedBounds = deriveBounds simpleSystem
598+
expectedBounds = Map.fromList [(0, Bounds (Just 1) (Just 0)), (1, Bounds (Just 3) (Just 1))]
599+
derivedBounds `shouldBe` expectedBounds
600+
validateBounds derivedBounds `shouldBe` False
601+
it "validateBounds finds that deriving bounds for a system where 1 <= x <= 0 and 1 <= y <= 3 has invalid bounds" $ do
602+
let simpleSystem =
603+
[ Expr (VarTerm 0) :>= 1
604+
, Expr (VarTerm 0) :<= 0
605+
, Expr (VarTerm 1) :>= 1
606+
, Expr (VarTerm 1) :<= 3
607+
]
608+
derivedBounds = deriveBounds simpleSystem
609+
expectedBounds = Map.fromList [(0, Bounds (Just 1) (Just 0)), (1, Bounds (Just 1) (Just 3))]
610+
derivedBounds `shouldBe` expectedBounds
611+
validateBounds derivedBounds `shouldBe` False
612+
it "validateBounds finds that deriving bounds for a system where 0 <= x <= 1 and 3 <= y <= 1 has invalid bounds" $ do
613+
let simpleSystem =
614+
[ Expr (VarTerm 0) :>= 0
615+
, Expr (VarTerm 0) :<= 1
616+
, Expr (VarTerm 1) :>= 3
617+
, Expr (VarTerm 1) :<= 1
618+
]
619+
derivedBounds = deriveBounds simpleSystem
620+
expectedBounds = Map.fromList [(0, Bounds (Just 0) (Just 1)), (1, Bounds (Just 3) (Just 1))]
621+
derivedBounds `shouldBe` expectedBounds
622+
validateBounds derivedBounds `shouldBe` False
623+
it "removeUselessSystemBounds removes x <= 3 when bounds say x <= 2" $ do
624+
let simpleSystem =
625+
[ Expr (VarTerm 0) :<= 2
626+
, Expr (VarTerm 0) :<= 3
627+
]
628+
bounds = Map.fromList [(0, Bounds (Just 0) (Just 2))]
629+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
630+
expectedSimpleSystem = [Expr (VarTerm 0) :<= 2]
631+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
632+
it "removeUselessSystemBounds does not remove x <= 2 when bounds say x <= 2" $ do
633+
let simpleSystem =
634+
[ Expr (VarTerm 0) :<= 2
635+
]
636+
bounds = Map.fromList [(0, Bounds (Just 0) (Just 2))]
637+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
638+
expectedSimpleSystem = [Expr (VarTerm 0) :<= 2]
639+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
640+
it "removeUselessSystemBounds removes x >= 3 when bounds say x >= 4" $ do
641+
let simpleSystem =
642+
[ Expr (VarTerm 0) :>= 4
643+
, Expr (VarTerm 0) :>= 3
644+
]
645+
bounds = Map.fromList [(0, Bounds (Just 4) (Just 5))]
646+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
647+
expectedSimpleSystem = [Expr (VarTerm 0) :>= 4]
648+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
649+
it "removeUselessSystemBounds does not remove x >= 4 when bounds say x >= 4" $ do
650+
let simpleSystem =
651+
[ Expr (VarTerm 0) :>= 4
652+
]
653+
bounds = Map.fromList [(0, Bounds (Just 4) (Just 5))]
654+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
655+
expectedSimpleSystem = [Expr (VarTerm 0) :>= 4]
656+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
657+
it "removeUselessSystemBounds does not remove 0 <= x <= 2 when bounds say 0 <= x <= 2" $ do
658+
let simpleSystem =
659+
[ Expr (VarTerm 0) :>= 0
660+
, Expr (VarTerm 0) :<= 2
661+
]
662+
bounds = Map.fromList [(0, Bounds (Just 0) (Just 2))]
663+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
664+
expectedSimpleSystem = [Expr (VarTerm 0) :>= 0, Expr (VarTerm 0) :<= 2]
665+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
666+
it "removeUselessSystemBounds removes upper bound of 0 <= x <= 2 when bounds say 0 <= x <= 1" $ do
667+
let simpleSystem =
668+
[ Expr (VarTerm 0) :>= 0
669+
, Expr (VarTerm 0) :<= 2
670+
]
671+
bounds = Map.fromList [(0, Bounds (Just 0) (Just 1))]
672+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
673+
expectedSimpleSystem = [Expr (VarTerm 0) :>= 0]
674+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
675+
it "removeUselessSystemBounds removes lower bound of 0 <= x <= 2 when bounds say 1 <= x <= 2" $ do
676+
let simpleSystem =
677+
[ Expr (VarTerm 0) :>= 0
678+
, Expr (VarTerm 0) :<= 2
679+
]
680+
bounds = Map.fromList [(0, Bounds (Just 1) (Just 2))]
681+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
682+
expectedSimpleSystem = [Expr (VarTerm 0) :<= 2]
683+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
684+
it "removeUselssSystemBounds only removes constraints of the form x <= c" $ do
685+
let simpleSystem =
686+
[ Expr (VarTerm 0) :<= 2
687+
, Expr (VarTerm 0) :<= 3
688+
, Expr (CoeffTerm 2 0) :<= 6
689+
]
690+
bounds = Map.fromList [(0, Bounds (Just 0) (Just 2))]
691+
simplifiedSimpleSystem = removeUselessSystemBounds simpleSystem bounds
692+
expectedSimpleSystem = [Expr (VarTerm 0) :<= 2, Expr (CoeffTerm 2 0) :<= 6]
693+
simplifiedSimpleSystem `shouldBe` expectedSimpleSystem
694+

0 commit comments

Comments
 (0)