packages feed

comfort-glpk-0.1: test/Test/Numeric/GLPK/Monad.hs

-- Do not edit! Automatically created with doctest-extract from src/Numeric/GLPK/Monad.hs
{-# LINE 42 "src/Numeric/GLPK/Monad.hs" #-}

{-# OPTIONS_GHC -XTypeFamilies #-}
{-# OPTIONS_GHC -XTypeOperators #-}
module Test.Numeric.GLPK.Monad where

import Test.DocTest.Base
import qualified Test.DocTest.Driver as DocTest

{-# LINE 45 "src/Numeric/GLPK/Monad.hs" #-}
import     qualified Numeric.LinearProgramming.Monad as LPMonad
import     qualified Numeric.LinearProgramming.Test as TestLP
import     qualified Numeric.GLPK.Monad as LP
import     qualified Numeric.GLPK as GLPK
import     Test.Numeric.GLPK.Utility
       (traverseLag, traverse_Lag, approxSuccession)
import     Test.Numeric.GLPK (TripletShape, tripletShape)
import     Numeric.GLPK (Bounds, Constraints, Objective, (.*), (<=.))

import     qualified Data.Array.Comfort.Storable as Array
import     qualified Data.Array.Comfort.Shape as Shape
import     qualified Data.NonEmpty as NonEmpty
import     Data.Array.Comfort.Storable (Array)
import     Data.Traversable (Traversable)
import     Data.Foldable (Foldable)

import     qualified Control.Monad.Trans.Except as ME

import     Data.Tuple.HT (mapSnd)

import     qualified Test.QuickCheck as QC


runSuccessive     ::
       (Eq sh, Shape.Indexed sh, Shape.Index sh ~ ix, Foldable t) =>
       sh ->
       Bounds ix ->
       (Constraints ix, (GLPK.Direction, Objective sh)) ->
       t (Double -> Constraints ix, (GLPK.Direction, Objective sh)) ->
       Either GLPK.FailureType ()
runSuccessive     shape bounds (constrs,dirObj) objs =
       LP.run shape bounds $ ME.runExceptT $ do
          (_solType, (opt, _xs)) <- ME.ExceptT $ LP.simplex constrs dirObj
          traverse_Lag opt
             (\prevResult (newConstr, dirObjI) -> do
                 (_solType, (optI, _xs)) <-
                    ME.ExceptT $ LP.simplex (newConstr prevResult) dirObjI
                 return optI)
             objs

solveSuccessiveWarm     ::
       (Eq sh, Shape.Indexed sh, Shape.Index sh ~ ix, Traversable t) =>
       sh ->
       Bounds ix ->
       (Constraints ix, (GLPK.Direction, Objective sh)) ->
       t (Double -> Constraints ix, (GLPK.Direction, Objective sh)) ->
       Either GLPK.FailureType
          (NonEmpty.T t (GLPK.SolutionType, (Double, Array sh Double)))
solveSuccessiveWarm     shape bounds (constrs,dirObj) objs =
       LP.run shape bounds $ ME.runExceptT $ do
          result <- ME.ExceptT $ LP.simplex constrs dirObj
          NonEmpty.Cons result <$>
             traverseLag result
                (\(_solType, (prevOpt, _xs)) (newConstr, dirObjI) ->
                    ME.ExceptT $ LP.simplex (newConstr prevOpt) dirObjI)
                objs

solveSuccessiveGen     ::
       (Eq sh, Shape.Indexed sh, Shape.Index sh ~ ix, Traversable t) =>
       sh ->
       Bounds ix ->
       (Constraints ix, (GLPK.Direction, Objective sh)) ->
       t (Double -> Constraints ix, (GLPK.Direction, Objective sh)) ->
       Either GLPK.FailureType
          (NonEmpty.T t (GLPK.SolutionType, (Double, Array sh Double)))
solveSuccessiveGen     shape bounds (constrs,dirObj) objs =
       LPMonad.run shape bounds $ ME.runExceptT $ do
          result <- ME.ExceptT $ LPMonad.lift GLPK.simplex constrs dirObj
          NonEmpty.Cons result <$>
             traverseLag result
                (\(_solType, (prevOpt, _xs)) (newConstr, dirObjI) ->
                    ME.ExceptT $
                       LPMonad.lift GLPK.simplex (newConstr prevOpt) dirObjI)
                objs

test :: DocTest.T ()
test = do
 DocTest.printPrefix "Numeric.GLPK.Monad:143: "
{-# LINE 143 "src/Numeric/GLPK/Monad.hs" #-}
 DocTest.property
{-# LINE 143 "src/Numeric/GLPK/Monad.hs" #-}
     (TestLP.forAllOrigin $ \origin -> TestLP.forAllProblem origin $ \bounds constrs -> QC.forAll (TestLP.genObjective origin) $ \(dir,obj) -> case (GLPK.simplex bounds constrs (dir,obj), LP.run (Array.shape origin) bounds $ LP.simplex constrs (dir,obj)) of (Right (GLPK.Optimal, (optA,_)), Right (GLPK.Optimal, (optB,_))) -> TestLP.approxReal 0.1 optA optB; _ -> False)
 DocTest.printPrefix "Numeric.GLPK.Monad:145: "
{-# LINE 145 "src/Numeric/GLPK/Monad.hs" #-}
 DocTest.property
{-# LINE 145 "src/Numeric/GLPK/Monad.hs" #-}
     (TestLP.forAllOrigin $ \origin -> TestLP.forAllProblem origin $ \bounds constrs -> TestLP.forAllObjectives origin $ \objs_ -> case TestLP.successiveObjectives origin 0.01 objs_ of (dirObj, objs) -> either (\msg -> QC.counterexample (show msg) False) (const $ QC.property True) $ runSuccessive (Array.shape origin) bounds (constrs,dirObj) objs)
 DocTest.printPrefix "Numeric.GLPK.Monad:147: "
{-# LINE 147 "src/Numeric/GLPK/Monad.hs" #-}
 DocTest.property
{-# LINE 147 "src/Numeric/GLPK/Monad.hs" #-}
     (TestLP.forAllOrigin $ \origin -> TestLP.forAllProblem origin $ \bounds constrs -> TestLP.forAllObjectives origin $ \objs_ -> case TestLP.successiveObjectives origin 0.01 objs_ of (dirObj, objs) -> approxSuccession 0.01 (solveSuccessiveWarm (Array.shape origin) bounds (constrs,dirObj) objs) (solveSuccessiveGen (Array.shape origin) bounds (constrs,dirObj) objs))
 DocTest.printPrefix "Numeric.GLPK.Monad:140: "
{-# LINE 140 "src/Numeric/GLPK/Monad.hs" #-}
 DocTest.example
{-# LINE 140 "src/Numeric/GLPK/Monad.hs" #-}
   (case Shape.indexTupleFromShape tripletShape of (x,y,z) -> mapSnd (mapSnd Array.toTuple) <$> LP.run tripletShape [] (LP.simplex [[2.*x, 1.*y] <=. 10, [1.*y, (5::Double).*z] <=. 20] (LP.Maximize, Array.fromTuple (4,-3,2) :: Array.Array TripletShape Double)))
  [ExpectedLine [LineChunk "Right (Optimal,(28.0,(5.0,0.0,4.0)))"]]