module Nlopt.NLP where
import Nlopt.Raw
import Ipopt.NLP
import Ipopt.AnyRF
import qualified Data.Sequence as Seq
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Storable.Mutable as VM
import qualified Data.Vector as V
import Control.Monad
import Control.Monad.State
import Control.Lens
import Foreign.C
import Control.Monad.Trans
import qualified Data.Foldable as F
import Control.Lens
solveNlopt :: (VG.Vector v Double, MonadIO m)
=> NloptAlgorithm
-> (NLOpt -> IO t)
-> NLPT m (v Double, Double, NloptResult)
solveNlopt alg moreOpts = do
(xl,xu) <- join $ uses (nlpfun . boundX) seqToVecs
gSeq <- use (nlpfun . boundG)
let ng = Seq.length gSeq
AnyRF fs <- use (nlpfun . funF)
AnyRF gs <- use (nlpfun . funG)
m <- liftIO . nloptCreate alg . (+1) =<< use (nMax . varIx)
x0 <- join $ uses initX (liftIO . VS.thaw . VG.convert)
gTol <- liftIO . VS.thaw . VS.fromList
=<< uses constraintTol (F.concatMap (\(a,b) -> [a,b]))
(status,obj) <- liftIO $ do
nloptSetMinObjective m (toFuncAD (F.sum . fs))
nloptSetLowerBounds m xl
nloptSetUpperBounds m xu
let toLE :: (AnyRFCxt a) => Seq.Seq a -> V.Vector a
toLE xs = V.fromList $ concatMap (\(x,(l,u)) -> [realToFrac lx,x realToFrac u])
(F.toList xs `zip` F.toList gSeq)
nloptAddInequalityMconstraint m (2*ng) (toFuncMAD (toLE . gs)) gTol
moreOpts m
nloptOptimize m x0
x <- liftIO (VS.freeze x0)
return (VG.convert x, obj, status)