lagrangian 0.1.0.0 → 0.2.0.0
raw patch · 4 files changed
+35/−10 lines, 4 filesdep ~ad
Dependency ranges changed: ad
Files
- lagrangian.cabal +28/−4
- src/Numeric/AD/Lagrangian.hs +1/−1
- src/Numeric/AD/Lagrangian/Internal.hs +4/−3
- tests/Main.hs +2/−2
lagrangian.cabal view
@@ -10,14 +10,38 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.1.0.0+version: 0.2.0.0 -- A short (one-line) description of the package. synopsis: Solve lagrangian multiplier problems -- A longer description of the package.--- description: -+description: + Numerically solve convex lagrange multiplier problems with conjugate gradient descent. + .+ Convexity is key, otherwise the descent algorithm can return the wrong answer.+ .+ Convexity can be tested by assuring that the hessian of the lagrangian is positive+ definite over region the function is defined in. + .+ I have provided test that the hessian is positive definite at a point, which is something,+ but not enough to ensure that the whole function is convex.+ .+ Be that as it may, if you know what the your lagrangian is convex you can use 'solve' to + find the minimum.+ .+ For example, find the maximum entropy with the constraint that the probabilities add+ up to one. + .+ @ + solve 0.00001 (negate . sum . map (\x -> x * log x), [(sum, 1)]) 3+ @+ .+ Gives the answer ([0.33, 0.33, 0.33], [-0.09])+ .+ The first elements of the result pair are the arguments for the objective function at the minimum. + The second elements are the lagrange multipliers.+ . -- URL for the project homepage or repository. homepage: http://github.com/jfischoff/lagrangian @@ -56,7 +80,7 @@ build-depends: base ==4.6.*, nonlinear-optimization ==0.3.*, vector ==0.10.*, - ad ==3.3.*,+ ad ==3.4.*, hmatrix == 0.14.* -- Directories containing source files.
src/Numeric/AD/Lagrangian.hs view
@@ -15,7 +15,7 @@ -- up to one. -- -- @ --- solve (negate . sum . map (\x -> x * log x), [(sum, 1)]) 3+-- solve 0.00001 (negate . sum . map (\x -> x * log x), [(sum, 1)]) 3 -- @ -- -- Gives the answer ([0.33, 0.33, 0.33], [-0.09])
src/Numeric/AD/Lagrangian/Internal.hs view
@@ -48,10 +48,11 @@ -- | This is the lagrangrain multiplier solver. It is assumed that the -- objective function and all of the constraints take in the -- same about of arguments.-solve :: (forall a. Floating a => ([a] -> a, [Constraint a])) -- ^ A pair of the function to minimize and the constraints+solve :: Double+ -> (forall a. Floating a => ([a] -> a, [Constraint a])) -- ^ A pair of the function to minimize and the constraints -> Int -- ^ The arity of the objective function and the constraints. -> Either (Result, Statistics) ([Double], [Double]) -- ^ Either an explaination of why the gradient descent failed or a pair of the arguments at the minimum and the lagrange multipliers-solve params argCount = result where+solve tolerance params argCount = result where obj :: Floating a => [a] -> a obj argsAndLams = squaredGrad lang argsAndLams @@ -63,7 +64,7 @@ guess = U.fromList $ replicate (argCount + constraintCount) (1.0 :: Double) result = case unsafePerformIO (optimize (defaultParameters { printFinal = False }) - 0.00001 guess (toFunction obj) (toGradient obj)+ tolerance guess (toFunction obj) (toGradient obj) Nothing) of (vs, ToleranceStatisfied, _) -> Right (take argCount . S.toList $ vs,
tests/Main.hs view
@@ -15,7 +15,7 @@ noConstraints = (fst <$> actual) @?= Right expected where- actual = solve (f, []) 1+ actual = solve 0.00001 (f, []) 1 expected = [1] f [x] = -(x - 1) ^2 @@ -24,7 +24,7 @@ entropyTest = (sum . map abs $ zipWith (-) actual expected) < 0.02 @?= True where- Right actual = fst <$> solve (f, [(\xs -> sum xs, 1.0)]) 3+ Right actual = fst <$> solve 0.00001 (f, [(\xs -> sum xs, 1.0)]) 3 expected = [0.33, 0.33, 0.33] f :: Floating a => [a] -> a f = negate . sum . map (\x -> x * log x)