packages feed

hmatrix-glpk 0.3.1 → 0.4.0

raw patch · 6 files changed

+473/−346 lines, 6 filesdep ~basedep ~hmatrixPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, hmatrix

API changes (from Hackage documentation)

- Numeric.LinearProgramming: (:=>:) :: x -> Double -> Bound x
+ Numeric.LinearProgramming: (:>=:) :: x -> Double -> Bound x
+ Numeric.LinearProgramming.L1: l1Solve :: Double -> Matrix Double -> Vector Double -> Vector Double
+ Numeric.LinearProgramming.L1: l1SolveGT :: Double -> Matrix Double -> Vector Double -> Vector Double
+ Numeric.LinearProgramming.L1: l1SolveO :: Matrix Double -> Vector Double -> Vector Double
+ Numeric.LinearProgramming.L1: l1SolveU :: Matrix Double -> Vector Double -> Vector Double
+ Numeric.LinearProgramming.L1: lInfSolveO :: Matrix Double -> Vector Double -> Vector Double

Files

hmatrix-glpk.cabal view
@@ -1,5 +1,5 @@ Name:               hmatrix-glpk-Version:            0.3.1+Version:            0.4.0 License:            GPL License-file:       LICENSE Author:             Alberto Ruiz@@ -11,7 +11,7 @@  Simple interface to linear programming functions provided by GLPK.  Category:           Math-tested-with:        GHC ==7.4+tested-with:        GHC ==7.8  cabal-version:      >=1.6 build-type:         Simple@@ -22,13 +22,14 @@                         examples/simplex4.hs  library-    Build-Depends:      base >= 3 && < 5, hmatrix >= 0.8.3+    Build-Depends:      base <5, hmatrix >= 0.16 -    hs-source-dirs:     lib+    hs-source-dirs:     src      Exposed-modules:    Numeric.LinearProgramming+                        Numeric.LinearProgramming.L1 -    c-sources:          lib/Numeric/LinearProgramming/glpk.c+    c-sources:          src/C/glpk.c      ghc-options:  -Wall 
− lib/Numeric/LinearProgramming.hs
@@ -1,265 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface #-}--{- |-Module      :  Numeric.LinearProgramming-Copyright   :  (c) Alberto Ruiz 2010-License     :  GPL--Maintainer  :  Alberto Ruiz (aruiz at um dot es)-Stability   :  provisional--This module provides an interface to the standard simplex algorithm.--For example, the following LP problem--@maximize 4 x_1 - 3 x_2 + 2 x_3-subject to--2 x_1 +   x_2 <= 10-  x_3 + 5 x_4 <= 20--and--x_i >= 0@--can be solved as follows:--@import Numeric.LinearProgramming--prob = Maximize [4, -3, 2]--constr1 = Sparse [ [2\#1, 1\#2] :<=: 10-                 , [1\#2, 5\#3] :<=: 20-                 ]--\> simplex prob constr1 []-Optimal (28.0,[5.0,0.0,4.0])@--The coefficients of the constraint matrix can also be given in dense format:--@constr2 = Dense [ [2,1,0] :<=: 10-                , [0,1,5] :<=: 20-                ]@--By default all variables are bounded as @x_i >= 0@, but this can be-changed:--@\> simplex prob constr2 [ 2 :=>: 1, 3 :&: (2,7)]-Optimal (22.6,[4.5,1.0,3.8])--\> simplex prob constr2 [Free 2]-Unbounded@--The given bound for a variable completely replaces the default,-so @0 <= x_i <= b@ must be explicitly given as @i :&: (0,b)@.-Multiple bounds for a variable are not allowed, instead of-@[i :=>: a, i:<=: b]@ use @i :&: (a,b)@.---}--module Numeric.LinearProgramming(-    simplex,-    Optimization(..),-    Constraints(..),-    Bounds,-    Bound(..),-    (#),-    Solution(..)-) where--import Numeric.LinearAlgebra hiding (i)-import Data.Packed.Development-import Foreign(Ptr)-import System.IO.Unsafe(unsafePerformIO)-import Foreign.C.Types-import Data.List((\\),sortBy,nub)-import Data.Function(on)----import Debug.Trace---debug x = trace (show x) x----------------------------------------------------------- | Coefficient of a variable for a sparse representation of constraints.-(#) :: Double -> Int -> (Double,Int)-infixl 5 #-(#) = (,)--data Bound x =  x :<=: Double-             |  x :=>: Double-             |  x :&: (Double,Double)-             |  x :==: Double-             |  Free x-             deriving Show--data Solution = Undefined-              | Feasible (Double, [Double])-              | Infeasible (Double, [Double])-              | NoFeasible-              | Optimal (Double, [Double])-              | Unbounded-              deriving Show--data Constraints = Dense  [ Bound [Double] ]-                 | Sparse [ Bound [(Double,Int)] ]--data Optimization = Maximize [Double]-                  | Minimize [Double]--type Bounds = [Bound Int]--simplex :: Optimization -> Constraints -> Bounds -> Solution--simplex opt (Dense  []) bnds = simplex opt (Sparse []) bnds-simplex opt (Sparse []) bnds = simplex opt (Sparse [Free [0#1]]) bnds--simplex opt (Dense constr) bnds = extract sg sol where-    sol = simplexSparse m n (mkConstrD sz objfun constr) (mkBounds sz constr bnds)-    n = length objfun-    m = length constr-    (sz, sg, objfun) = adapt opt--simplex opt (Sparse constr) bnds = extract sg sol where-    sol = simplexSparse m n (mkConstrS sz objfun constr) (mkBounds sz constr bnds)-    n = length objfun-    m = length constr-    (sz, sg, objfun) = adapt opt--adapt :: Optimization -> (Int, Double, [Double])-adapt opt = case opt of-    Maximize x -> (size x, 1 ,x)-    Minimize x -> (size x, -1, (map negate x))- where size x | null x = error "simplex: objective function with zero variables"-              | otherwise = length x--extract :: Double -> Vector Double -> Solution-extract sg sol = r where-    z = sg * (sol@>1)-    v = toList $ subVector 2 (dim sol -2) sol-    r = case round(sol@>0)::Int of-          1 -> Undefined-          2 -> Feasible (z,v)-          3 -> Infeasible (z,v)-          4 -> NoFeasible-          5 -> Optimal (z,v)-          6 -> Unbounded-          _ -> error "simplex: solution type unknown"---------------------------------------------------------obj :: Bound t -> t-obj (x :<=: _)  = x-obj (x :=>: _)  = x-obj (x :&: _)  = x-obj (x :==: _) = x-obj (Free x)   = x--tb :: Bound t -> Double-tb (_ :<=: _)  = glpUP-tb (_ :=>: _)  = glpLO-tb (_ :&: _)  = glpDB-tb (_ :==: _) = glpFX-tb (Free _)   = glpFR--lb :: Bound t -> Double-lb (_ :<=: _)     = 0-lb (_ :=>: a)     = a-lb (_ :&: (a,_)) = a-lb (_ :==: a)    = a-lb (Free _)      = 0--ub :: Bound t -> Double-ub (_ :<=: a)     = a-ub (_ :=>: _)     = 0-ub (_ :&: (_,a)) = a-ub (_ :==: a)    = a-ub (Free _)      = 0--mkBound1 :: Bound t -> [Double]-mkBound1 b = [tb b, lb b, ub b]--mkBound2 :: Bound t -> (t, [Double])-mkBound2 b = (obj b, mkBound1 b)--mkBounds :: Int -> [Bound [a]] -> [Bound Int] -> Matrix Double-mkBounds n b1 b2 = fromLists (cb++vb) where-    gv' = map obj b2-    gv | nub gv' == gv' = gv'-       | otherwise = error $ "simplex: duplicate bounds for vars " ++ show (gv'\\nub gv')-    rv | null gv || minimum gv >= 0 && maximum gv <= n = [1..n] \\ gv-       | otherwise = error $ "simplex: bounds: variables "++show gv++" not in 1.."++show n-    vb = map snd $ sortBy (compare `on` fst) $ map (mkBound2 . (:=>: 0)) rv ++ map mkBound2 b2-    cb = map mkBound1 b1--mkConstrD :: Int -> [Double] -> [Bound [Double]] -> Matrix Double-mkConstrD n f b1 | ok = fromLists (ob ++ co)-                 | otherwise = error $ "simplex: dense constraints require "++show n-                                     ++" variables, given " ++ show ls-    where-       cs = map obj b1-       ls = map length cs-       ok = all (==n) ls-       den = fromLists cs-       ob = map (([0,0]++).return) f-       co = [[fromIntegral i, fromIntegral j,den@@>(i-1,j-1)]| i<-[1 ..rows den], j<-[1 .. cols den]]--mkConstrS :: Int -> [Double] -> [Bound [(Double, Int)]] -> Matrix Double-mkConstrS n objfun b1 = fromLists (ob ++ co) where-    ob = map (([0,0]++).return) objfun-    co = concat $ zipWith f [1::Int ..] cs-    cs = map obj b1-    f k = map (g k)-    g k (c,v) | v >=1 && v<= n = [fromIntegral k, fromIntegral v,c]-              | otherwise = error $ "simplex: sparse constraints: variable "++show v++" not in 1.."++show n---------------------------------------------------------foreign import ccall unsafe "c_simplex_sparse" c_simplex_sparse-    :: CInt -> CInt                  -- rows and cols-    -> CInt -> CInt -> Ptr Double    -- coeffs-    -> CInt -> CInt -> Ptr Double    -- bounds-    -> CInt -> Ptr Double            -- result-    -> IO CInt                       -- exit code--simplexSparse :: Int -> Int -> Matrix Double -> Matrix Double -> Vector Double-simplexSparse m n c b = unsafePerformIO $ do-    s <- createVector (2+n)-    let fi = fromIntegral-    app3 (c_simplex_sparse (fi m) (fi n)) mat (cmat c) mat (cmat b) vec s "c_simplex_sparse"-    return s--glpFR, glpLO, glpUP, glpDB, glpFX :: Double-glpFR = 0-glpLO = 1-glpUP = 2-glpDB = 3-glpFX = 4--{- Raw format of coeffs--simplexSparse--(12><3)- [ 0.0, 0.0, 10.0- , 0.0, 0.0,  6.0- , 0.0, 0.0,  4.0- , 1.0, 1.0,  1.0- , 1.0, 2.0,  1.0- , 1.0, 3.0,  1.0- , 2.0, 1.0, 10.0- , 2.0, 2.0,  4.0- , 2.0, 3.0,  5.0- , 3.0, 1.0,  2.0- , 3.0, 2.0,  2.0- , 3.0, 3.0,  6.0 ]--bounds = (6><3)-  [ glpUP,0,100-  , glpUP,0,600-  , glpUP,0,300-  , glpLO,0,0-  , glpLO,0,0-  , glpLO,0,0 ]---}-
− lib/Numeric/LinearProgramming/glpk.c
@@ -1,76 +0,0 @@-#define DVEC(A) int A##n, double*A##p-#define DMAT(A) int A##r, int A##c, double*A##p--#define AT(M,r,co) (M##p[(r)*M##c+(co)])--#include <stdlib.h>-#include <stdio.h>-#include <glpk.h>-#include <math.h>--/*-----------------------------------------------------*/--int c_simplex_sparse(int m, int n, DMAT(c), DMAT(b), DVEC(s)) {-    glp_prob *lp;-    lp = glp_create_prob();-    glp_set_obj_dir(lp, GLP_MAX);-    int i,j,k;-    int tot = cr - n;-    glp_add_rows(lp, m);-    glp_add_cols(lp, n);--    //printf("%d %d\n",m,n);--    // the first n values-    for (k=1;k<=n;k++) {-        glp_set_obj_coef(lp, k, AT(c, k-1, 2));-        //printf("%d %f\n",k,AT(c, k-1, 2));-    }--    int * ia = malloc((1+tot)*sizeof(int));-    int * ja = malloc((1+tot)*sizeof(int));-    double * ar = malloc((1+tot)*sizeof(double));--    for (k=1; k<= tot; k++) {-        ia[k] = rint(AT(c,k-1+n,0));-        ja[k] = rint(AT(c,k-1+n,1));-        ar[k] =      AT(c,k-1+n,2);-        //printf("%d %d %f\n",ia[k],ja[k],ar[k]);-    }-    glp_load_matrix(lp, tot, ia, ja, ar);--    int t;-    for (i=1;i<=m;i++) {-    switch((int)rint(AT(b,i-1,0))) {-        case 0: { t = GLP_FR; break; }-        case 1: { t = GLP_LO; break; }-        case 2: { t = GLP_UP; break; }-        case 3: { t = GLP_DB; break; }-       default: { t = GLP_FX; break; }-    }-    glp_set_row_bnds(lp, i, t , AT(b,i-1,1), AT(b,i-1,2));-    }-    for (j=1;j<=n;j++) {-    switch((int)rint(AT(b,m+j-1,0))) {-        case 0: { t = GLP_FR; break; }-        case 1: { t = GLP_LO; break; }-        case 2: { t = GLP_UP; break; }-        case 3: { t = GLP_DB; break; }-       default: { t = GLP_FX; break; }-    }-    glp_set_col_bnds(lp, j, t , AT(b,m+j-1,1), AT(b,m+j-1,2));-    }-    glp_term_out(0);-    glp_simplex(lp, NULL);-    sp[0] = glp_get_status(lp);-    sp[1] = glp_get_obj_val(lp);-    for (k=1; k<=n; k++) {-        sp[k+1] = glp_get_col_prim(lp, k);-    }-    glp_delete_prob(lp);-    free(ia);-    free(ja);-    free(ar);--    return 0;-}
+ src/C/glpk.c view
@@ -0,0 +1,76 @@+#define DVEC(A) int A##n, double*A##p+#define DMAT(A) int A##r, int A##c, double*A##p++#define AT(M,r,co) (M##p[(r)*M##c+(co)])++#include <stdlib.h>+#include <stdio.h>+#include <glpk.h>+#include <math.h>++/*-----------------------------------------------------*/++int c_simplex_sparse(int m, int n, DMAT(c), DMAT(b), DVEC(s)) {+    glp_prob *lp;+    lp = glp_create_prob();+    glp_set_obj_dir(lp, GLP_MAX);+    int i,j,k;+    int tot = cr - n;+    glp_add_rows(lp, m);+    glp_add_cols(lp, n);++    //printf("%d %d\n",m,n);++    // the first n values+    for (k=1;k<=n;k++) {+        glp_set_obj_coef(lp, k, AT(c, k-1, 2));+        //printf("%d %f\n",k,AT(c, k-1, 2));+    }++    int * ia = malloc((1+tot)*sizeof(int));+    int * ja = malloc((1+tot)*sizeof(int));+    double * ar = malloc((1+tot)*sizeof(double));++    for (k=1; k<= tot; k++) {+        ia[k] = rint(AT(c,k-1+n,0));+        ja[k] = rint(AT(c,k-1+n,1));+        ar[k] =      AT(c,k-1+n,2);+        //printf("%d %d %f\n",ia[k],ja[k],ar[k]);+    }+    glp_load_matrix(lp, tot, ia, ja, ar);++    int t;+    for (i=1;i<=m;i++) {+    switch((int)rint(AT(b,i-1,0))) {+        case 0: { t = GLP_FR; break; }+        case 1: { t = GLP_LO; break; }+        case 2: { t = GLP_UP; break; }+        case 3: { t = GLP_DB; break; }+       default: { t = GLP_FX; break; }+    }+    glp_set_row_bnds(lp, i, t , AT(b,i-1,1), AT(b,i-1,2));+    }+    for (j=1;j<=n;j++) {+    switch((int)rint(AT(b,m+j-1,0))) {+        case 0: { t = GLP_FR; break; }+        case 1: { t = GLP_LO; break; }+        case 2: { t = GLP_UP; break; }+        case 3: { t = GLP_DB; break; }+       default: { t = GLP_FX; break; }+    }+    glp_set_col_bnds(lp, j, t , AT(b,m+j-1,1), AT(b,m+j-1,2));+    }+    glp_term_out(0);+    glp_simplex(lp, NULL);+    sp[0] = glp_get_status(lp);+    sp[1] = glp_get_obj_val(lp);+    for (k=1; k<=n; k++) {+        sp[k+1] = glp_get_col_prim(lp, k);+    }+    glp_delete_prob(lp);+    free(ia);+    free(ja);+    free(ar);++    return 0;+}
+ src/Numeric/LinearProgramming.hs view
@@ -0,0 +1,271 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{- |+Module      :  Numeric.LinearProgramming+Copyright   :  (c) Alberto Ruiz 2010+License     :  GPL++Maintainer  :  Alberto Ruiz+Stability   :  provisional++This module provides an interface to the standard simplex algorithm.++For example, the following LP problem+++maximize 4 x_1 - 3 x_2 + 2 x_3+subject to++2 x_1 +   x_2 <= 10+  x_3 + 5 x_4 <= 20++and++x_i >= 0+++can be solved as follows:++@+import Numeric.LinearProgramming++prob = Maximize [4, -3, 2]++constr1 = Sparse [ [2\#1, 1\#2] :<=: 10+                 , [1\#2, 5\#3] :<=: 20+                 ]+@++>>> simplex prob constr1 []+Optimal (28.0,[5.0,0.0,4.0])+++The coefficients of the constraint matrix can also be given in dense format:++@+constr2 = Dense [ [2,1,0] :<=: 10+                , [0,1,5] :<=: 20+                ]+@++By default all variables are bounded as @x_i >= 0@, but this can be+changed:++>>> simplex prob constr2 [ 2 :>=: 1, 3 :&: (2,7)]+Optimal (22.6,[4.5,1.0,3.8])++>>> simplex prob constr2 [Free 2]+Unbounded++The given bound for a variable completely replaces the default,+so @0 <= x_i <= b@ must be explicitly given as @i :&: (0,b)@.+Multiple bounds for a variable are not allowed, instead of+@[i :>=: a, i:<=: b]@ use @i :&: (a,b)@.++-}++module Numeric.LinearProgramming(+    simplex,+    Optimization(..),+    Constraints(..),+    Bounds,+    Bound(..),+    (#),+    Solution(..)+) where++import Data.Packed+import Data.Packed.Development+import Foreign(Ptr)+import System.IO.Unsafe(unsafePerformIO)+import Foreign.C.Types+import Data.List((\\),sortBy,nub)+import Data.Function(on)++--import Debug.Trace+--debug x = trace (show x) x++-----------------------------------------------------++-- | Coefficient of a variable for a sparse representation of constraints.+(#) :: Double -> Int -> (Double,Int)+infixl 5 #+(#) = (,)++data Bound x =  x :<=: Double+             |  x :>=: Double+             |  x :&: (Double,Double)+             |  x :==: Double+             |  Free x+             deriving Show++data Solution = Undefined+              | Feasible (Double, [Double])+              | Infeasible (Double, [Double])+              | NoFeasible+              | Optimal (Double, [Double])+              | Unbounded+              deriving Show++data Constraints = Dense  [ Bound [Double] ]+                 | Sparse [ Bound [(Double,Int)] ]++data Optimization = Maximize [Double]+                  | Minimize [Double]++type Bounds = [Bound Int]++simplex :: Optimization -> Constraints -> Bounds -> Solution++simplex opt (Dense  []) bnds = simplex opt (Sparse []) bnds+simplex opt (Sparse []) bnds = simplex opt (Sparse [Free [0#1]]) bnds++simplex opt (Dense constr) bnds = extract sg sol where+    sol = simplexSparse m n (mkConstrD sz objfun constr) (mkBounds sz constr bnds)+    n = length objfun+    m = length constr+    (sz, sg, objfun) = adapt opt++simplex opt (Sparse constr) bnds = extract sg sol where+    sol = simplexSparse m n (mkConstrS sz objfun constr) (mkBounds sz constr bnds)+    n = length objfun+    m = length constr+    (sz, sg, objfun) = adapt opt++adapt :: Optimization -> (Int, Double, [Double])+adapt opt = case opt of+    Maximize x -> (size x, 1 ,x)+    Minimize x -> (size x, -1, (map negate x))+ where size x | null x = error "simplex: objective function with zero variables"+              | otherwise = length x++extract :: Double -> Vector Double -> Solution+extract sg sol = r where+    z = sg * (sol@>1)+    v = toList $ subVector 2 (dim sol -2) sol+    r = case round(sol@>0)::Int of+          1 -> Undefined+          2 -> Feasible (z,v)+          3 -> Infeasible (z,v)+          4 -> NoFeasible+          5 -> Optimal (z,v)+          6 -> Unbounded+          _ -> error "simplex: solution type unknown"++-----------------------------------------------------++obj :: Bound t -> t+obj (x :<=: _)  = x+obj (x :>=: _)  = x+obj (x :&: _)  = x+obj (x :==: _) = x+obj (Free x)   = x++tb :: Bound t -> Double+tb (_ :<=: _)  = glpUP+tb (_ :>=: _)  = glpLO+tb (_ :&: _)  = glpDB+tb (_ :==: _) = glpFX+tb (Free _)   = glpFR++lb :: Bound t -> Double+lb (_ :<=: _)     = 0+lb (_ :>=: a)     = a+lb (_ :&: (a,_)) = a+lb (_ :==: a)    = a+lb (Free _)      = 0++ub :: Bound t -> Double+ub (_ :<=: a)     = a+ub (_ :>=: _)     = 0+ub (_ :&: (_,a)) = a+ub (_ :==: a)    = a+ub (Free _)      = 0++mkBound1 :: Bound t -> [Double]+mkBound1 b = [tb b, lb b, ub b]++mkBound2 :: Bound t -> (t, [Double])+mkBound2 b = (obj b, mkBound1 b)++mkBounds :: Int -> [Bound [a]] -> [Bound Int] -> Matrix Double+mkBounds n b1 b2 = fromLists (cb++vb) where+    gv' = map obj b2+    gv | nub gv' == gv' = gv'+       | otherwise = error $ "simplex: duplicate bounds for vars " ++ show (gv'\\nub gv')+    rv | null gv || minimum gv >= 0 && maximum gv <= n = [1..n] \\ gv+       | otherwise = error $ "simplex: bounds: variables "++show gv++" not in 1.."++show n+    vb = map snd $ sortBy (compare `on` fst) $ map (mkBound2 . (:>=: 0)) rv ++ map mkBound2 b2+    cb = map mkBound1 b1++mkConstrD :: Int -> [Double] -> [Bound [Double]] -> Matrix Double+mkConstrD n f b1 | ok = fromLists (ob ++ co)+                 | otherwise = error $ "simplex: dense constraints require "++show n+                                     ++" variables, given " ++ show ls+    where+       cs = map obj b1+       ls = map length cs+       ok = all (==n) ls+       den = fromLists cs+       ob = map (([0,0]++).return) f+       co = [[fromIntegral i, fromIntegral j,den@@>(i-1,j-1)]| i<-[1 ..rows den], j<-[1 .. cols den]]++mkConstrS :: Int -> [Double] -> [Bound [(Double, Int)]] -> Matrix Double+mkConstrS n objfun b1 = fromLists (ob ++ co) where+    ob = map (([0,0]++).return) objfun+    co = concat $ zipWith f [1::Int ..] cs+    cs = map obj b1+    f k = map (g k)+    g k (c,v) | v >=1 && v<= n = [fromIntegral k, fromIntegral v,c]+              | otherwise = error $ "simplex: sparse constraints: variable "++show v++" not in 1.."++show n++-----------------------------------------------------++foreign import ccall unsafe "c_simplex_sparse" c_simplex_sparse+    :: CInt -> CInt                  -- rows and cols+    -> CInt -> CInt -> Ptr Double    -- coeffs+    -> CInt -> CInt -> Ptr Double    -- bounds+    -> CInt -> Ptr Double            -- result+    -> IO CInt                       -- exit code++simplexSparse :: Int -> Int -> Matrix Double -> Matrix Double -> Vector Double+simplexSparse m n c b = unsafePerformIO $ do+    s <- createVector (2+n)+    app3 (c_simplex_sparse (fi m) (fi n)) mat (cmat c) mat (cmat b) vec s "c_simplex_sparse"+    return s++glpFR, glpLO, glpUP, glpDB, glpFX :: Double+glpFR = 0+glpLO = 1+glpUP = 2+glpDB = 3+glpFX = 4++{- Raw format of coeffs++simplexSparse++(12><3)+ [ 0.0, 0.0, 10.0+ , 0.0, 0.0,  6.0+ , 0.0, 0.0,  4.0+ , 1.0, 1.0,  1.0+ , 1.0, 2.0,  1.0+ , 1.0, 3.0,  1.0+ , 2.0, 1.0, 10.0+ , 2.0, 2.0,  4.0+ , 2.0, 3.0,  5.0+ , 3.0, 1.0,  2.0+ , 3.0, 2.0,  2.0+ , 3.0, 3.0,  6.0 ]++bounds = (6><3)+  [ glpUP,0,100+  , glpUP,0,600+  , glpUP,0,300+  , glpLO,0,0+  , glpLO,0,0+  , glpLO,0,0 ]++-}+
+ src/Numeric/LinearProgramming/L1.hs view
@@ -0,0 +1,120 @@+{- |+Module      :  Numeric.LinearProgramming.L1+Copyright   :  (c) Alberto Ruiz 2011-14+Stability   :  provisional++Linear system solvers in the L_1 norm using linear programming.++-}+-----------------------------------------------------------------------------++module Numeric.LinearProgramming.L1 (+    l1Solve, l1SolveGT,+    l1SolveO, lInfSolveO,+    l1SolveU,+) where++import Numeric.LinearAlgebra+import Numeric.LinearProgramming++-- | L_inf solution of overconstrained system Ax=b.+--+-- @argmin_x ||Ax-b||_inf@+lInfSolveO :: Matrix Double -> Vector Double -> Vector Double+lInfSolveO a b = fromList (take n x)+  where+    n = cols a+    as = toRows a+    bs = toList b+    c1 = zipWith (mk (1)) as bs+    c2 = zipWith (mk (-1)) as bs+    mk sign a_i b_i = (zipWith (#) (toList (scale sign a_i)) [1..] ++ [-1#(n+1)]) :<=: (sign * b_i)+    p = Sparse (c1++c2)+    Optimal (_j,x) = simplex (Minimize (replicate n 0 ++ [1])) p (map Free [1..(n+1)])++--------------------------------------------------------------------------------++-- | L_1 solution of overconstrained system Ax=b.+--+-- @argmin_x ||Ax-b||_1@+l1SolveO :: Matrix Double -> Vector Double -> Vector Double+l1SolveO a b = fromList (take n x)+  where+    n = cols a+    m = rows a+    as = toRows a+    bs = toList b+    ks = [1..]+    c1 = zipWith3 (mk (1)) as bs ks+    c2 = zipWith3 (mk (-1)) as bs ks+    mk sign a_i b_i k = (zipWith (#) (toList (scale sign a_i)) [1..] ++ [-1#(k+n)]) :<=: (sign * b_i)+    p = Sparse (c1++c2)+    Optimal (_j,x) = simplex (Minimize (replicate n 0 ++ replicate m 1)) p (map Free [1..(n+m)])++--------------------------------------------------------------------------------++-- | L1 solution of underconstrained linear system Ax=b.+--+-- @argmin_x ||x||_1 such that Ax=b@+l1SolveU :: Matrix Double -> Vector Double -> Vector Double+l1SolveU a y = fromList (take n x)+  where+    n = cols a+    c1 = map (\k ->  [ 1#k, -1#k+n] :<=: 0) [1..n]+    c2 = map (\k ->  [-1#k, -1#k+n] :<=: 0) [1..n]+    c3 = zipWith (:==:) (map sp $ toRows a) (toList y)+    sp v = zipWith (#) (toList v) [1..]+    p = Sparse (c1 ++ c2 ++ c3)+    Optimal (_j,x) = simplex (Minimize (replicate n 0 ++ replicate n 1)) p (map Free [1..(2*n)])++--------------------------------------------------------------------------------+-- | Solution in the L_1 norm, with L_1 regularization, of a linear system @Ax=b@.+--+-- @argmin_x  λ||x||_1 + ||Ax-b||_1@+l1Solve+    :: Double        -- ^ λ+    -> Matrix Double -- ^ A+    -> Vector Double -- ^ b+    -> Vector Double -- ^ x+l1Solve λ a b = fromList (take n x)+  where+    n = cols a+    m = rows a+    as = toRows a+    bs = toList b+    c1Res = zipWith3 (mkR (1)) as bs [1..m]+    c2Res = zipWith3 (mkR (-1)) as bs [1..m]+    mkR sign a_i b_i k = (zipWith (#) (toList (scale sign a_i)) [1..] ++ [-1#(k+2*n)]) :<=: (sign * b_i)+    c1Sol = map (\k ->  [ 1#k, -1#k+n] :<=: 0) [1..n]+    c2Sol = map (\k ->  [-1#k, -1#k+n] :<=: 0) [1..n]+    p = Sparse (c1Res++c2Res++c1Sol++c2Sol)+    cost = replicate n 0 ++ replicate n λ ++ replicate m 1+    Optimal (_j,x) = simplex (Minimize cost) p (map Free [1..(2*n+m)])++--------------------------------------------------------------------------------++-- | Solution in the L_1 norm, with L_1 regularization, of a system of linear inequalities @Ax>=b@.+--+-- @argmin_x  λ||x||_1 + ||step(b-Ax)||_1@+l1SolveGT+    :: Double        -- ^ λ+    -> Matrix Double -- ^ A+    -> Vector Double -- ^ b+    -> Vector Double -- ^ x+l1SolveGT λ a b = fromList (take n x)+  where+    n = cols a+    m = rows a+    as = toRows a+    bs = toList b+    cRes = zipWith3 mkR as bs [1..m]+    mkR a_i b_i k = (zipWith (#) (toList a_i) [1..] ++ [1#(k+2*n)]) :>=: (b_i)+    c1Sol = map (\k ->  [ 1#k, -1#k+n] :<=: 0) [1..n]+    c2Sol = map (\k ->  [-1#k, -1#k+n] :<=: 0) [1..n]+    p = Sparse (cRes++c1Sol++c2Sol)+    cost = replicate n 0 ++ replicate n λ ++ replicate m 1+    Optimal (_j,x) = simplex (Minimize cost) p (map Free [1..(2*n)])++--------------------------------------------------------------------------------++