packages feed

sparse-linear-algebra 0.2.0.8 → 0.2.0.9

raw patch · 9 files changed

+316/−233 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Numeric.LinearAlgebra.Sparse.IntMap: countSubdiagonalNZ :: IntMap (IntMap a) -> Int
- Numeric.LinearAlgebra.Sparse.IntMap: filterSubdiag :: IntMap (IntMap a) -> IntMap (IntMap a)
- Numeric.LinearAlgebra.Sparse.IntMap: foldlIM2 :: (a -> b -> b) -> b -> IntMap (IntMap a) -> b
- Numeric.LinearAlgebra.Sparse.IntMap: fromListIM2 :: Foldable t => t (Key, Key, a) -> IntMap (IntMap a) -> IntMap (IntMap a)
- Numeric.LinearAlgebra.Sparse.IntMap: ifilterIM2 :: (Key -> Key -> a -> Bool) -> IntMap (IntMap a) -> IntMap (IntMap a)
- Numeric.LinearAlgebra.Sparse.IntMap: ifoldlIM2 :: (Key -> Key -> t -> IntMap a -> IntMap a) -> IntMap (IntMap t) -> IntMap a
- Numeric.LinearAlgebra.Sparse.IntMap: ifoldlIM2' :: (Key -> Key -> a -> b -> b) -> b -> IntMap (IntMap a) -> b
- Numeric.LinearAlgebra.Sparse.IntMap: imapIM2 :: (Key -> Key -> a -> b) -> IntMap (IntMap a) -> IntMap (IntMap b)
- Numeric.LinearAlgebra.Sparse.IntMap: insertIM2 :: Key -> Key -> a -> IntMap (IntMap a) -> IntMap (IntMap a)
- Numeric.LinearAlgebra.Sparse.IntMap: instance Numeric.LinearAlgebra.Class.Additive Data.IntMap.Base.IntMap
- Numeric.LinearAlgebra.Sparse.IntMap: instance Numeric.LinearAlgebra.Class.Hilbert Data.IntMap.Base.IntMap
- Numeric.LinearAlgebra.Sparse.IntMap: instance Numeric.LinearAlgebra.Class.Normed Data.IntMap.Base.IntMap
- Numeric.LinearAlgebra.Sparse.IntMap: instance Numeric.LinearAlgebra.Class.Set Data.IntMap.Base.IntMap
- Numeric.LinearAlgebra.Sparse.IntMap: instance Numeric.LinearAlgebra.Class.VectorSpace Data.IntMap.Base.IntMap
- Numeric.LinearAlgebra.Sparse.IntMap: lookupIM2 :: Key -> Key -> IntMap (IntMap a) -> Maybe a
- Numeric.LinearAlgebra.Sparse.IntMap: mapColumnIM2 :: (b -> b) -> IntMap (IntMap b) -> Int -> IntMap (IntMap b)
- Numeric.LinearAlgebra.Sparse.IntMap: mapIM2 :: (a -> b) -> IntMap (IntMap a) -> IntMap (IntMap b)
- Numeric.LinearAlgebra.Sparse.IntMap: mapKeysIM2 :: (Key -> Key) -> (Key -> Key) -> IntMap (IntMap a) -> IntMap (IntMap a)
- Numeric.LinearAlgebra.Sparse.IntMap: rpairs :: (a, [b]) -> [(a, b)]
- Numeric.LinearAlgebra.Sparse.IntMap: subdiagIndices :: IntMap (IntMap a) -> [(Key, Key)]
- Numeric.LinearAlgebra.Sparse.IntMap: transposeIM2 :: IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.IntMap2.IntMap2: countSubdiagonalNZ :: IntMap (IntMap a) -> Int
+ Data.Sparse.IntMap2.IntMap2: filterSubdiag :: IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.IntMap2.IntMap2: foldlIM2 :: (a -> b -> b) -> b -> IntMap (IntMap a) -> b
+ Data.Sparse.IntMap2.IntMap2: fromListIM2 :: Foldable t => t (Key, Key, a) -> IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.IntMap2.IntMap2: ifilterIM2 :: (Key -> Key -> a -> Bool) -> IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.IntMap2.IntMap2: ifoldlIM2 :: (Key -> Key -> t -> IntMap a -> IntMap a) -> IntMap (IntMap t) -> IntMap a
+ Data.Sparse.IntMap2.IntMap2: ifoldlIM2' :: (Key -> Key -> a -> b -> b) -> b -> IntMap (IntMap a) -> b
+ Data.Sparse.IntMap2.IntMap2: imapIM2 :: (Key -> Key -> a -> b) -> IntMap (IntMap a) -> IntMap (IntMap b)
+ Data.Sparse.IntMap2.IntMap2: insertIM2 :: Key -> Key -> a -> IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.IntMap2.IntMap2: instance Numeric.LinearAlgebra.Class.Additive Data.IntMap.Base.IntMap
+ Data.Sparse.IntMap2.IntMap2: instance Numeric.LinearAlgebra.Class.Hilbert Data.IntMap.Base.IntMap
+ Data.Sparse.IntMap2.IntMap2: instance Numeric.LinearAlgebra.Class.Normed Data.IntMap.Base.IntMap
+ Data.Sparse.IntMap2.IntMap2: instance Numeric.LinearAlgebra.Class.Set Data.IntMap.Base.IntMap
+ Data.Sparse.IntMap2.IntMap2: instance Numeric.LinearAlgebra.Class.VectorSpace Data.IntMap.Base.IntMap
+ Data.Sparse.IntMap2.IntMap2: lookupIM2 :: Key -> Key -> IntMap (IntMap a) -> Maybe a
+ Data.Sparse.IntMap2.IntMap2: mapColumnIM2 :: (b -> b) -> IntMap (IntMap b) -> Int -> IntMap (IntMap b)
+ Data.Sparse.IntMap2.IntMap2: mapIM2 :: (a -> b) -> IntMap (IntMap a) -> IntMap (IntMap b)
+ Data.Sparse.IntMap2.IntMap2: mapKeysIM2 :: (Key -> Key) -> (Key -> Key) -> IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.IntMap2.IntMap2: rpairs :: (a, [b]) -> [(a, b)]
+ Data.Sparse.IntMap2.IntMap2: subdiagIndices :: IntMap (IntMap a) -> [(Key, Key)]
+ Data.Sparse.IntMap2.IntMap2: transposeIM2 :: IntMap (IntMap a) -> IntMap (IntMap a)
+ Data.Sparse.SpMatrix: extractDiag :: SpMatrix a -> SpMatrix a
+ Data.Sparse.SpMatrix: extractSubDiag :: SpMatrix a -> SpMatrix a
+ Data.Sparse.SpMatrix: extractSuperDiag :: SpMatrix a -> SpMatrix a
+ Data.Sparse.SpMatrix: filterSM :: (Key -> Key -> a -> Bool) -> SpMatrix a -> SpMatrix a
+ Numeric.LinearAlgebra.Sparse: diagPartitions :: SpMatrix a -> (SpMatrix a, SpMatrix a, SpMatrix a)
+ Numeric.LinearAlgebra.Sparse: ilu0 :: SpMatrix Double -> (SpMatrix Double, SpMatrix Double)
+ Numeric.LinearAlgebra.Sparse: randArray :: PrimMonad m => Int -> Double -> Double -> m [Double]

Files

README.md view
@@ -77,7 +77,7 @@     [0.0,0.0,5.0]  Notice that the result is _dense_, i.e. certain entries are numerically zero but have been inserted into the result along with all the others (thus taking up memory!).-To preserve sparsity, we can use a sparsifying matrix-matrix product `#~#`, which filters out all the elements x for which `|x| <= eps`, where `eps` (defined) in `Numeric.Eps`, is fixed at 10^-8.+To preserve sparsity, we can use a sparsifying matrix-matrix product `#~#`, which filters out all the elements x for which `|x| <= eps`, where `eps` (defined in `Numeric.Eps`) is fixed at 10^-8.      > prd $ l #~# u     ( 3 rows, 3 columns ) , 5 NZ ( sparsity 0.5555555555555556 )
sparse-linear-algebra.cabal view
@@ -1,5 +1,5 @@ name:                sparse-linear-algebra-version:             0.2.0.8+version:             0.2.0.9 synopsis:            Numerical computation in native Haskell  description:         Currently the library provides iterative linear solvers, matrix decompositions, eigenvalue computations and related utilities. Please see README.md for details homepage:            https://github.com/ocramz/sparse-linear-algebra@@ -20,7 +20,7 @@   hs-source-dirs:      src   exposed-modules:     Numeric.LinearAlgebra.Sparse                        Numeric.LinearAlgebra.Class-                       Numeric.LinearAlgebra.Sparse.IntMap+                       Data.Sparse.IntMap2.IntMap2                        Data.Sparse.SpVector                        Data.Sparse.SpMatrix                        Data.Sparse.Common
src/Data/Sparse/Common.hs view
@@ -12,13 +12,12 @@  import Data.Sparse.Utils as X import Data.Sparse.Types as X+import Data.Sparse.IntMap2.IntMap2 as X import Data.Sparse.SpMatrix as X import Data.Sparse.SpVector as X  import Numeric.Eps as X import Numeric.LinearAlgebra.Class as X--import Numeric.LinearAlgebra.Sparse.IntMap as X  import qualified Data.IntMap as IM 
+ src/Data/Sparse/IntMap2/IntMap2.hs view
@@ -0,0 +1,187 @@+module Data.Sparse.IntMap2.IntMap2 where++import Numeric.LinearAlgebra.Class++import qualified Data.IntMap.Strict as IM++++++instance Set IM.IntMap where+  liftU2 = IM.unionWith+  {-# INLINE liftU2 #-}+  liftI2 = IM.intersectionWith+  {-# INLINE liftI2 #-}++instance Additive IM.IntMap where+  zero = IM.empty+  {-# INLINE zero #-}+  (^+^) = liftU2 (+)+  {-# INLINE (^+^) #-}+++instance VectorSpace IM.IntMap where+  n .* im = IM.map (* n) im+  +instance Hilbert IM.IntMap where+   a `dot` b = sum $ liftI2 (*) a b+              ++instance Normed IM.IntMap where+  norm p v | p==1 = norm1 v+           | p==2 = norm2 v+           | otherwise = normP p v++++-- * set-like brackets+++-- unionWithKeyIM2 f im1 im2 = undefined where++++++-- * Insertion++-- | Insert an element+insertIM2 ::+  IM.Key -> IM.Key -> a -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)+insertIM2 i j x imm = IM.insert i ro imm where+  ro = maybe (IM.singleton j x) (IM.insert j x) (IM.lookup i imm)+{-# inline insertIM2 #-}  ++-- * Lookup++-- |Lookup a key+lookupIM2 ::+  IM.Key -> IM.Key -> IM.IntMap (IM.IntMap a) -> Maybe a+lookupIM2 i j imm = IM.lookup i imm >>= IM.lookup j+{-# inline lookupIM2 #-}  ++-- |Ppopulate an IM2 from a list of (row index, column index, value)  +fromListIM2 ::+  Foldable t =>+     t (IM.Key, IM.Key, a) -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)+fromListIM2 iix sm = foldl ins sm iix where+  ins t (i,j,x) = insertIM2 i j x t+++-- * Folding++-- |Indexed left fold over an IM2, with general accumulator+ifoldlIM2' :: (IM.Key -> IM.Key -> a -> b -> b) -> b -> IM.IntMap (IM.IntMap a) -> b+ifoldlIM2' f empty mm = IM.foldlWithKey' accRow empty mm where+  accRow acc i r = IM.foldlWithKey' (accElem i) acc r+  accElem i acc j x = f i j x acc+{-# inline ifoldlIM2' #-}++-- |Indexed left fold over an IM2+ifoldlIM2 ::+  (IM.Key -> IM.Key -> t -> IM.IntMap a -> IM.IntMap a) ->+  IM.IntMap (IM.IntMap t) ->  +  IM.IntMap a+ifoldlIM2 f m         = IM.foldlWithKey' accRow IM.empty m where+  accRow    acc i row = IM.foldlWithKey' (accElem i) acc row+  accElem i acc j x   = f i j x acc+{-# inline ifoldlIM2 #-}  ++-- |Left fold over an IM2, with general accumulator+foldlIM2 :: (a -> b -> b) -> b -> IM.IntMap (IM.IntMap a) -> b+foldlIM2 f empty mm = IM.foldl accRow empty mm where+  accRow acc r = IM.foldl accElem acc r+  accElem acc x = f x acc+{-# inline foldlIM2 #-}+++-- | Inner indices become outer ones and vice versa. No loss of information because both inner and outer IntMaps are nubbed.+transposeIM2 :: IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)+transposeIM2 = ifoldlIM2 (flip insertIM2)+{-# inline transposeIM2 #-}++-- specialized folds++-- -- extract diagonal elements+-- extractDiagonalIM2 :: IM.IntMap (IM.IntMap a) -> [a]+-- extractDiagonalIM2 = ifoldlIM2' (\i j x xs -> if i==j then x : xs else xs) []+++++-- * filtering++-- |Map over outer IM and filter all inner IM's+ifilterIM2 ::+  (IM.Key -> IM.Key -> a -> Bool) ->+  IM.IntMap (IM.IntMap a) ->+  IM.IntMap (IM.IntMap a)+ifilterIM2 f  =+  IM.mapWithKey (\irow row -> IM.filterWithKey (f irow) row) +{-# inline ifilterIM2 #-}++-- |Specialized filtering : keep only sub-diagonal elements+filterSubdiag :: IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)+filterSubdiag = ifilterIM2 (\i j _ -> i>j)++countSubdiagonalNZ :: IM.IntMap (IM.IntMap a) -> Int+countSubdiagonalNZ im =+  IM.size $ IM.filter (not . IM.null) (filterSubdiag im)++-- |List of (row, col) indices of (nonzero) subdiagonal elements+subdiagIndices :: IM.IntMap (IM.IntMap a) -> [(IM.Key, IM.Key)]+subdiagIndices im = concatMap rpairs $ IM.toList (IM.map IM.keys im') where+  im' = filterSubdiag im++rpairs :: (a, [b]) -> [(a, b)]+rpairs (i, jj@(_:_)) = zip (replicate (length jj) i) jj+rpairs (_, []) = []++-- -- list of (row, col) indices of elements that satisfy a criterion+-- indicesThatIM2 ::+--   (IM.Key -> IM.IntMap a -> Bool) -> IM.IntMap (IM.IntMap a) -> [(IM.Key, IM.Key)]+-- indicesThatIM2 f im = concatMap rpairs $ IM.toList (IM.map IM.keys im') where+--   im' = IM.filterWithKey f im++  +++-- * Mapping++-- |Map over IM2+mapIM2 :: (a -> b) -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap b)+mapIM2 = IM.map . IM.map   -- imapIM2 (\_ _ x -> f x)++++++-- |Indexed map over IM2+imapIM2 ::+  (IM.Key -> IM.Key -> a -> b) ->+  IM.IntMap (IM.IntMap a) ->+  IM.IntMap (IM.IntMap b)+imapIM2 f im = IM.mapWithKey ff im where+  ff j x = IM.mapWithKey (`f` j) x++++-- |Mapping keys+mapKeysIM2 ::+  (IM.Key -> IM.Key) -> (IM.Key -> IM.Key) -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)+mapKeysIM2 fi fj im = IM.map adjCols adjRows where+  adjRows = IM.mapKeys fi im+  adjCols = IM.mapKeys fj +++++-- map over a single `column`++mapColumnIM2 :: (b -> b) -> IM.IntMap (IM.IntMap b) -> Int -> IM.IntMap (IM.IntMap b)+mapColumnIM2 f im jj = imapIM2 (\i j x -> if j == jj then f x else x) im++++
src/Data/Sparse/SpMatrix.hs view
@@ -7,7 +7,7 @@ import Numeric.Eps import Numeric.LinearAlgebra.Class -import Numeric.LinearAlgebra.Sparse.IntMap+import Data.Sparse.IntMap2.IntMap2  import qualified Data.IntMap as IM @@ -209,7 +209,20 @@  -- ** Sub-matrices +-- | Indexed filtering function+filterSM :: (IM.Key -> IM.Key -> a -> Bool) -> SpMatrix a -> SpMatrix a+filterSM f sm = SM (dim sm) $ ifilterIM2 f (dat sm) +-- | Diagonal, subdiagonal, superdiagonal partitions of a SpMatrix (useful for writing preconditioners)+extractDiag, extractSuperDiag, extractSubDiag :: SpMatrix a -> SpMatrix a+extractSubDiag = filterSM (\i j _ -> i > j)++extractSuperDiag = filterSM (\i j _ -> i < j)++extractDiag = filterSM (\i j _ -> i == j)+++ -- | Extract a submatrix given the specified index bounds, rebalancing keys with the two supplied functions extractSubmatrixSM ::   (IM.Key -> IM.Key) ->   -- row index function@@ -582,6 +595,12 @@ -- ** Multiply matrix by a scalar matScale :: Num a => a -> SpMatrix a -> SpMatrix a matScale a = fmap (*a)++++++  -- ** Frobenius norm normFrobenius :: SpMatrix Double -> Double
src/Data/Sparse/SpVector.hs view
@@ -5,7 +5,7 @@ import Data.Sparse.Types  import Numeric.LinearAlgebra.Class-import Numeric.LinearAlgebra.Sparse.IntMap+import Data.Sparse.IntMap2.IntMap2  import Data.Maybe 
src/Numeric/LinearAlgebra/Sparse.hs view
@@ -4,6 +4,8 @@        (          -- * Matrix factorizations          qr, lu,+         -- * Incomplete LU+         ilu0,          -- * Condition number          conditionNumberSM,          -- * Householder reflection@@ -19,6 +21,10 @@          _xCgne, _xTfq, _xBicgstab, _x, _xBcg,          cgsStep, bicgstabStep,          CGNE, TFQMR, BICGSTAB, CGS, BCG,+         -- * Matrix partitioning+         diagPartitions,+         -- * Random arrays+         randArray,          -- * Random matrices and vectors          randMat, randVec,           -- ** Sparse "@@ -434,12 +440,15 @@ -- * Incomplete LU  -- | used for Incomplete LU : remove entries in `m` corresponding to zero entries in `m2`-ripHoles :: SpMatrix t -> SpMatrix a -> SpMatrix a-ripHoles (SM d m) m2 = SM d $ ifilterIM2 f (dat m2) where-  f i j _ = isJust (lookupSM m2 i j)   +ilu0 aa = (lh, uh) where+  (l, u) = lu aa+  lh = sparsifyLU l aa+  uh = sparsifyLU u aa+  sparsifyLU m m2 = SM (dim m) $ ifilterIM2 f (dat m) where+    f i j _ = isJust (lookupSM m2 i j)   @@ -450,7 +459,33 @@   +-- * Preconditioning +-- | Partition a matrix into strictly subdiagonal, diagonal and strictly superdiagonal parts+diagPartitions :: SpMatrix a -> (SpMatrix a, SpMatrix a, SpMatrix a)+diagPartitions aa = (e,d,f) where+  e = extractSubDiag aa+  d = extractDiag aa+  f = extractSuperDiag aa+++-- ** SSOR++-- | `mSsor aa omega` : if `omega = 1` it returns the diagonal of `aa`, +mSsor :: Fractional a => SpMatrix a -> a -> SpMatrix a+mSsor aa omega = l ## r where+  (e, d, f) = diagPartitions aa+  n = nrows e+  l = d ^-^ scale omega e+  r = eye n ^-^ scale omega (reciprocal d ## f)++++++++ -- * Iterative linear solvers  @@ -843,8 +878,16 @@   +-- * Random arrays +randArray :: PrimMonad m => Int -> Double -> Double -> m [Double]+randArray n mu sig = do+  g <- MWC.create+  replicateM n (MWC.normal mu sig g)+   ++ -- * Random matrices and vectors  -- |Dense SpMatrix@@ -884,4 +927,6 @@   aav <- replicateM nsp (MWC.normal 0 1 g)   ii <- replicateM nsp (MWC.uniformR (0, n-1) g :: IO Int)   return $ fromListSV n $ zip ii aav++ 
− src/Numeric/LinearAlgebra/Sparse/IntMap.hs
@@ -1,184 +0,0 @@-module Numeric.LinearAlgebra.Sparse.IntMap where--import Numeric.LinearAlgebra.Class--import qualified Data.IntMap.Strict as IM------instance Set IM.IntMap where-  liftU2 = IM.unionWith-  {-# INLINE liftU2 #-}-  liftI2 = IM.intersectionWith-  {-# INLINE liftI2 #-}--instance Additive IM.IntMap where-  zero = IM.empty-  {-# INLINE zero #-}-  (^+^) = liftU2 (+)-  {-# INLINE (^+^) #-}---instance VectorSpace IM.IntMap where-  n .* im = IM.map (* n) im-  -instance Hilbert IM.IntMap where-   a `dot` b = sum $ liftI2 (*) a b-              --instance Normed IM.IntMap where-  norm p v | p==1 = norm1 v-           | p==2 = norm2 v-           | otherwise = normP p v------ * set-like brackets----- unionWithKeyIM2 f im1 im2 = undefined where-------- * Insertion---- | Insert an element-insertIM2 ::-  IM.Key -> IM.Key -> a -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)-insertIM2 i j x imm = IM.insert i ro imm where-  ro = maybe (IM.singleton j x) (IM.insert j x) (IM.lookup i imm)-{-# inline insertIM2 #-}  ---- * Lookup---- |Lookup a key-lookupIM2 ::-  IM.Key -> IM.Key -> IM.IntMap (IM.IntMap a) -> Maybe a-lookupIM2 i j imm = IM.lookup i imm >>= IM.lookup j-{-# inline lookupIM2 #-}  ---- |Ppopulate an IM2 from a list of (row index, column index, value)  -fromListIM2 ::-  Foldable t =>-     t (IM.Key, IM.Key, a) -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)-fromListIM2 iix sm = foldl ins sm iix where-  ins t (i,j,x) = insertIM2 i j x t----- * folding---- |Indexed left fold over an IM2, with general accumulator-ifoldlIM2' :: (IM.Key -> IM.Key -> a -> b -> b) -> b -> IM.IntMap (IM.IntMap a) -> b-ifoldlIM2' f empty mm = IM.foldlWithKey' accRow empty mm where-  accRow acc i r = IM.foldlWithKey' (accElem i) acc r-  accElem i acc j x = f i j x acc-{-# inline ifoldlIM2' #-}---- |Indexed left fold over an IM2-ifoldlIM2 ::-  (IM.Key -> IM.Key -> t -> IM.IntMap a -> IM.IntMap a) ->-  IM.IntMap (IM.IntMap t) ->  -  IM.IntMap a-ifoldlIM2 f m         = IM.foldlWithKey' accRow IM.empty m where-  accRow    acc i row = IM.foldlWithKey' (accElem i) acc row-  accElem i acc j x   = f i j x acc-{-# inline ifoldlIM2 #-}  ---- |Left fold over an IM2, with general accumulator-foldlIM2 :: (a -> b -> b) -> b -> IM.IntMap (IM.IntMap a) -> b-foldlIM2 f empty mm = IM.foldl accRow empty mm where-  accRow acc r = IM.foldl accElem acc r-  accElem acc x = f x acc-{-# inline foldlIM2 #-}----- | Inner indices become outer ones and vice versa. No loss of information because both inner and outer IntMaps are nubbed.-transposeIM2 :: IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)-transposeIM2 = ifoldlIM2 (flip insertIM2)-{-# inline transposeIM2 #-}---- specialized folds---- -- extract diagonal elements--- extractDiagonalIM2 :: IM.IntMap (IM.IntMap a) -> [a]--- extractDiagonalIM2 = ifoldlIM2' (\i j x xs -> if i==j then x : xs else xs) []------- * filtering---- |Map over outer IM and filter all inner IM's-ifilterIM2 ::-  (IM.Key -> IM.Key -> a -> Bool) ->-  IM.IntMap (IM.IntMap a) ->-  IM.IntMap (IM.IntMap a)-ifilterIM2 f  =-  IM.mapWithKey (\irow row -> IM.filterWithKey (f irow) row) -{-# inline ifilterIM2 #-}---- |Specialized filtering : keep only sub-diagonal elements-filterSubdiag :: IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)-filterSubdiag = ifilterIM2 (\i j _ -> i>j)--countSubdiagonalNZ :: IM.IntMap (IM.IntMap a) -> Int-countSubdiagonalNZ im =-  IM.size $ IM.filter (not . IM.null) (filterSubdiag im)---- |List of (row, col) indices of (nonzero) subdiagonal elements-subdiagIndices :: IM.IntMap (IM.IntMap a) -> [(IM.Key, IM.Key)]-subdiagIndices im = concatMap rpairs $ IM.toList (IM.map IM.keys im') where-  im' = filterSubdiag im--rpairs :: (a, [b]) -> [(a, b)]-rpairs (i, jj@(_:_)) = zip (replicate (length jj) i) jj-rpairs (_, []) = []---- -- list of (row, col) indices of elements that satisfy a criterion--- indicesThatIM2 ::---   (IM.Key -> IM.IntMap a -> Bool) -> IM.IntMap (IM.IntMap a) -> [(IM.Key, IM.Key)]--- indicesThatIM2 f im = concatMap rpairs $ IM.toList (IM.map IM.keys im') where---   im' = IM.filterWithKey f im--  ----- * mapping---- |Map over IM2-mapIM2 :: (a -> b) -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap b)-mapIM2 = IM.map . IM.map   -- imapIM2 (\_ _ x -> f x)----- |Indexed map over IM2-imapIM2 ::-  (IM.Key -> IM.Key -> a -> b) ->-  IM.IntMap (IM.IntMap a) ->-  IM.IntMap (IM.IntMap b)-imapIM2 f im = IM.mapWithKey ff im where-  ff j x = IM.mapWithKey (`f` j) x------ |Mapping keys-mapKeysIM2 ::-  (IM.Key -> IM.Key) -> (IM.Key -> IM.Key) -> IM.IntMap (IM.IntMap a) -> IM.IntMap (IM.IntMap a)-mapKeysIM2 fi fj im = IM.map adjCols adjRows where-  adjRows = IM.mapKeys fi im-  adjCols = IM.mapKeys fj ------- map over a single `column`--mapColumnIM2 :: (b -> b) -> IM.IntMap (IM.IntMap b) -> Int -> IM.IntMap (IM.IntMap b)-mapColumnIM2 f im jj = imapIM2 (\i j x -> if j == jj then f x else x) im----
test/LibSpec.hs view
@@ -4,6 +4,10 @@ import Numeric.LinearAlgebra.Sparse -- import Numeric.LinearAlgebra.Class +import Control.Monad (liftM, liftM2)+import Control.Monad.Primitive+import Data.Foldable (foldrM)+ import Data.Sparse.Common  @@ -155,33 +159,63 @@   --- dense-solveRandom n = do-  aa0 <- randMat n-  let aa = aa0 ^+^ eye n-  xtrue <- randVec n-  -- x0 <- randVec n-  let b = aa #> xtrue-      dx = aa <\> b ^-^ xtrue-  return $ normSq dx-  -- let xhatB = _xBicgstab (bicgstab aa b x0 x0)-  --     xhatC = _x (cgs aa b x0 x0)-  -- return (aa, x, x0, b, xhatB, xhatC)+-- -- dense+-- solveRandom n = do+--   aa0 <- randMat n+--   let aa = aa0 ^+^ eye n+--   xtrue <- randVec n+--   -- x0 <- randVec n+--   let b = aa #> xtrue+--       dx = aa <\> b ^-^ xtrue+--   return $ normSq dx+--   -- let xhatB = _xBicgstab (bicgstab aa b x0 x0)+--   --     xhatC = _x (cgs aa b x0 x0)+--   -- return (aa, x, x0, b, xhatB, xhatC) --- sparse-solveSpRandom :: Int -> Int -> IO Double-solveSpRandom n nsp = do-  aa0 <- randSpMat n nsp-  let aa = aa0 ^+^ eye n-  xtrue <- randSpVec n nsp-  let b = (aa ^+^ eye n) #> xtrue-      dx = aa <\> b ^-^ xtrue-  return $ normSq dx+-- -- sparse+-- solveSpRandom :: Int -> Int -> IO Double+-- solveSpRandom n nsp = do+--   aa0 <- randSpMat n nsp+--   let aa = aa0 ^+^ eye n+--   xtrue <- randSpVec n nsp+--   let b = (aa ^+^ eye n) #> xtrue+--       dx = aa <\> b ^-^ xtrue+--   return $ normSq dx    +-- solveRandomBanded n bw mu sig = do+--   let ndiags = 2*bw+--   bands <- replicateM (ndiags + 1) (randArray n mu sig)+--   xtrue <- randVec n+--   b <- randVec n+--   let+--     diags = [-bw .. bw - 1] +randDiagMat :: PrimMonad m =>+     Rows -> Double -> Double -> Int -> m (SpMatrix Double)+randDiagMat n mu sig i = do+  x <- randArray n mu sig+  return $ mkSubDiagonal n i x+++go (m:ms) mat =+  m ^+^ go ms mat+go [] mat = mat++  +plusM x y = return $ x ^+^ y++++++++++ --  {-@@ -213,25 +247,8 @@  {- mkSubDiagonal -} -testLaplacian1 :: Int -> SpMatrix Double-testLaplacian1 n = m where-  m :: SpMatrix Double-  m = mksd (-1) l1 ^+^-       mksd 0 l2 ^+^-       mksd 1 l3-    where-    mksd = mkSubDiagonal n-    l1 = replicate n (-1)-    l2 = replicate n 2-    l3 = l1-  -- x :: SpVector Double-  -- x = mkSpVectorD n (replicate n 2)-  -- b = m #> x --- t3 n = normSq $ (aa <\> b) ^-^ xhat where---   aa = testLaplacian1 n :: SpMatrix Double---   xhat = mkSpVectorD n (concat $ replicate 20 [1,2,3,4,5]) :: SpVector Double---   b = aa #> xhat+  {- QR-}