cmaes 0.1.0.1 → 0.1.1
raw patch · 3 files changed
+75/−27 lines, 3 filesdep +randomdep +vectorPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: random, vector
API changes (from Hackage documentation)
+ Numeric.Optimization.Algorithms.CMAES: noiseEps :: Config tgt -> Maybe Double
+ Numeric.Optimization.Algorithms.CMAES: noiseHandling :: Config tgt -> Bool
+ Numeric.Optimization.Algorithms.CMAES: noiseReEvals :: Config tgt -> Maybe Int
- Numeric.Optimization.Algorithms.CMAES: Config :: (tgt -> IO Double) -> (tgt -> [Double]) -> ([Double] -> tgt) -> [Double] -> Double -> Maybe [Double] -> Maybe [Double] -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Int -> Maybe Double -> Bool -> Config tgt
+ Numeric.Optimization.Algorithms.CMAES: Config :: (tgt -> IO Double) -> (tgt -> [Double]) -> ([Double] -> tgt) -> [Double] -> Double -> Maybe [Double] -> Maybe [Double] -> Bool -> Maybe Int -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Int -> Maybe Double -> Bool -> Config tgt
Files
- LICENSE +2/−2
- Numeric/Optimization/Algorithms/CMAES.hs +63/−24
- cmaes.cabal +10/−1
LICENSE view
@@ -1,4 +1,4 @@ This package is an aggregate of programs. cma.py (c) Nikolaus Hansen,-2008-2012 is redistributed under GPL 2 or 3. The other programs (c)-Takayuki Muranushi are licensed under MIT license. See the files+2008-2012 is redistributed under GPL 2 or 3. All the other components+(c) Takayuki Muranushi are licensed under MIT license. See the files LICENSE.GPL2, LICENSE.GPL3 and LICENSE.MIT for more details.
Numeric/Optimization/Algorithms/CMAES.hs view
@@ -6,16 +6,14 @@ Usage: -(1) create an optimization problem of type @Config@ by one of- @minimize@, @minimizeIO@ etc.--(2) @run@ it.-+(1) create an optimization problem of type `Config` by one of+ `minimize`, `minimizeIO` etc. +(2) `run` it. -Let's optimize the following function /f(xs)/. @xs@ is a vector and-@f@ has its minimum at @xs !! i = sqrt(i)@.+Let's optimize the following function /f(xs)/. @xs@ is a list of+Double and @f@ has its minimum at @xs !! i = sqrt(i)@. >>> import Test.DocTest.Prop >>> let f = sum . zipWith (\i x -> (x*abs x - i)**2) [0..] :: [Double] -> Double@@ -25,10 +23,10 @@ If your optimization is not working well, try: -* Set @scaling@ in the @Config@ to the appropriate search+* Set `scaling` in the `Config` to the appropriate search range of each parameter. -* Set @tolFun@ in the @Config@ to the appropriate scale of+* Set `tolFun` in the `Config` to the appropriate scale of the function values. An example for scaling the function value:@@ -41,11 +39,11 @@ >>> let f3 xs = sum $ zipWith (\i x -> (x*abs x - i)**2) [0,1e100..] xs >>> let xs30 = replicate 10 0 :: [Double]->>> let m3 = (minimize f3 xs30) {scaling = Just (replicate 10 1e50)}+>>> let m3 = (minimize f3 xs30) {scaling = Just (repeat 1e50)} >>> xs31 <- run $ m3 >>> assert $ f3 xs31 / f3 xs30 < 1e-10 -Use @minimizeT@ to optimize functions on traversable structures.+Use `minimizeT` to optimize functions on traversable structures. >>> import qualified Data.Vector as V >>> let f4 = V.sum . V.imap (\i x -> (x*abs x - fromIntegral i)**2) :: V.Vector Double -> Double@@ -54,7 +52,7 @@ -Or use @minimizeG@ to optimize functions of almost any type. Let's create a triangle ABC+Or use `minimizeG` to optimize functions of almost any type. Let's create a triangle ABC so that AB = 3, AC = 4, BC = 5. >>> let dist (ax,ay) (bx,by) = ((ax-bx)**2 + (ay-by)**2)**0.5@@ -69,7 +67,19 @@ >>> assert $ abs ((bx-ax)*(cx-ax) + (by-ay)*(cy-ay)) < 1e-10 +When optimizing noisy functions, set `noiseHandling` = @True@ for better results. +>>> import System.Random+>>> let noise = randomRIO (0,1e-2)+>>> let f6Pure = sum . zipWith (\i x -> (x*abs x - i)**2) [0..]+>>> let f6 xs = fmap (f6Pure xs +) noise+>>> xs60 <- run $ (minimizeIO f6 $ replicate 10 0) {noiseHandling = False}+>>> xs61 <- run $ (minimizeIO f6 $ replicate 10 0) {noiseHandling = True}+>>> assert $ f6Pure xs61 < f6Pure xs60++++ -} @@ -81,6 +91,7 @@ )where +import Control.Applicative ((<|>)) import Control.Monad hiding (forM_, mapM) import qualified Control.Monad.State as State import Data.Data@@ -112,8 +123,19 @@ -- ^ The global scaling factor. , scaling :: Maybe [Double] -- ^ Typical deviation of each input parameters.+ -- The length of the list is adjusted to be the same as+ -- initXs, e.g. you can lazily use an infinite list here. , typicalXs :: Maybe [Double] -- ^ Typical mean of each input parameters.+ -- The length of this list too, is adjusted to be the same as+ -- initXs.+ , noiseHandling :: Bool+ -- ^ Assume the function to be rugged and/or noisy+ , noiseReEvals :: Maybe Int+ -- ^ How many re-evaluation to make to estimate the noise.+ , noiseEps :: Maybe Double+ -- ^ Perturb the parameters by this amount (relative to sigma)+ -- to estimate the noise , tolFacUpX :: Maybe Double -- ^ Terminate when one of the scaling grew too big -- (initial scaling was too small.)@@ -143,6 +165,9 @@ , sigma0 = 0.25 , scaling = Nothing , typicalXs = Nothing+ , noiseHandling = False+ , noiseReEvals = Nothing+ , noiseEps = Just 1e-7 , tolFacUpX = Just 1e10 , tolUpSigma = Just 1e20 , tolFun = Just 1e-11@@ -223,10 +248,24 @@ fail "ohmy god" loop where+ probDim :: Int+ probDim = length initXs++ adjustDim :: [a] -> [a] -> [a]+ adjustDim supply orig =+ take probDim $+ catMaybes $+ zipWith (<|>)+ (map Just orig ++ repeat Nothing)+ (map Just supply)+ options :: [(String, String)] options = concat $ map maybeToList- [ "scaling_of_variables" `is` scaling- , "typical_x" `is` typicalXs+ [ "scaling_of_variables" `is` (fmap$adjustDim [1..] ) scaling+ , "typical_x" `is` (fmap$adjustDim initXs) typicalXs+ , "noise_handling" `is` Just noiseHandling+ , "noise_reevals" `is` noiseReEvals+ , "noise_eps" `is` noiseEps , "tolfacupx" `is` tolFacUpX , "tolupsigma" `is` tolUpSigma , "tolfunhist" `is` tolFun@@ -295,7 +334,7 @@ -} -getDoubles :: Data d => d -> [Double]+getDoubles :: Data a => a -> [Double] getDoubles d = reverse $ State.execState (everywhereM getter d) [] where getter :: GenericM (State.State [Double])@@ -304,19 +343,19 @@ let da = fmap (flip asTypeOf (head ys)) $ cast a case da of Nothing -> return a- Just d -> do- State.put $ d:ys+ Just dd -> do+ State.put $ dd:ys return a -putDoubles :: Data d => [Double] -> d -> d+putDoubles :: Data a => [Double] -> a -> a putDoubles ys0 d = State.evalState (everywhereM putter d) ys0 where putter :: GenericM (State.State [Double])- putter a = do+ putter a0 = do ys <- State.get- let ma' = (cast =<<) $ fmap (asTypeOf (head ys)) $ cast a- case ma' of- Nothing -> return a- Just a' -> do+ let ma1 = (cast =<<) $ fmap (asTypeOf (head ys)) $ cast a0+ case ma1 of+ Nothing -> return a0+ Just a1 -> do State.put $ tail ys- return a'+ return a1
cmaes.cabal view
@@ -1,5 +1,5 @@ name: cmaes-version: 0.1.0.1+version: 0.1.1 synopsis: CMA-ES wrapper in Haskell description: @@ -9,7 +9,14 @@ package you need python2 with numpy available on your system. The package includes @cma.py@ , Nikolaus Hansen's production-level CMA library: <http://www.lri.fr/~hansen/cmaes_inmatlab.html#python>.+ .+ This package is an aggregate of programs. cma.py (c) Nikolaus+ Hansen, 2008-2012 is redistributed under GPL 2 or 3. All the other+ components (c) Takayuki Muranushi are licensed under MIT+ license. See the files LICENSE.GPL2, LICENSE.GPL3 and LICENSE.MIT+ for more details. + license: OtherLicense license-file: LICENSE author: Takayuki Muranushi@@ -40,7 +47,9 @@ , doctest-prop >=0.2 , mtl , process+ , random , syb+ , vector source-repository head type: git