packages feed

HNumeric 0.4.0.0 → 0.5.0.0

raw patch · 8 files changed

+240/−88 lines, 8 filesdep +math-functionsdep +paralleldep −normaldistributionPVP ok

version bump matches the API change (PVP)

Dependencies added: math-functions, parallel

Dependencies removed: normaldistribution

API changes (from Hackage documentation)

- HNum.CSV: cm :: [String] -> String
- HNum.F: instance HNum.F.FuncTools HNum.Vector.Matrix
- HNum.F: instance HNum.F.FuncTools HNum.Vector.Vector
- HNum.Vector: (!) :: List m => m a -> Int -> a
+ HNum.Special: class FuncTools f => SpecialFunc f
+ HNum.Special: erf :: (SpecialFunc f, Real a) => f a -> f Double
+ HNum.Special: instance HNum.Special.SpecialFunc HNum.Vector.Vector
+ HNum.Special: invErf :: (SpecialFunc f, Real a) => f a -> f Double
+ HNum.Vector: (.!) :: List m => m a -> Int -> a
+ HNum.Vector: determinant :: Num a => [[a]] -> a
+ HNum.Vector: elemPos :: [[a]] -> Int -> Int -> a
+ HNum.Vector: instance HNum.F.FuncTools HNum.Vector.Matrix
+ HNum.Vector: instance HNum.F.FuncTools HNum.Vector.Vector
+ HNum.Vector: permanent :: Num a => [[a]] -> a
+ HNum.Vector: prod :: Num a => ([[a]] -> Int -> Int -> a) -> [[a]] -> [Int] -> a
+ HNum.Vector: sDeterminant :: Num a => ([[a]] -> Int -> Int -> a) -> [[a]] -> [([Int], Int)] -> a
+ HNum.Vector: sPermutations :: [a] -> [([a], Int)]

Files

ChangeLog.md view
@@ -1,5 +1,11 @@ # Changelog for HNumeric ++## 0.5.0.0++* Great Optimisation with parallel+* Fix infinite determinant by Rosetta stone+ ## 0.4.0.0  * Add HNum.F (Functional Programming Library for HNum)
HNumeric.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: a31a8bb1239bf98ba7561f43ae6c7fe1005cd190658fb003dd7a222ffd8ae071+-- hash: 9cfd5649e8b6b63aa2edca51c427be56f671256d05794ce8eaed484e456a0e1c  name:           HNumeric-version:        0.4.0.0+version:        0.5.0.0 synopsis:       Haskell Numeric Library with pure functionality, R & MATLAB Syntax. description:    Please see the README on GitHub at <https://github.com/Axect/HNumeric#readme> category:       HNum, library, Numeric, LinearAlgebra, Statistics, bsd3@@ -30,6 +30,7 @@   exposed-modules:       HNum.CSV       HNum.F+      HNum.Special       HNum.Stats       HNum.Vector   other-modules:@@ -38,7 +39,8 @@       src   build-depends:       base >=4.7 && <5-    , normaldistribution+    , math-functions+    , parallel     , random   default-language: Haskell2010 @@ -53,6 +55,7 @@   build-depends:       HNumeric     , base >=4.7 && <5-    , normaldistribution+    , math-functions+    , parallel     , random   default-language: Haskell2010
README.md view
@@ -4,10 +4,11 @@  ## Packages -* HNum.Vector : Contain vector, matrix, linear algebra-* HNum.Stats  : Contain statistical functions-* HNum.CSV    : CSV Tools for HNum (Contain DataFrame)-* HNum.F      : Functional Programming Tools for HNum+* HNum.Vector  : Contain vector, matrix, linear algebra+* HNum.Stats   : Contain statistical functions+* HNum.CSV     : CSV Tools for HNum (Contain DataFrame)+* HNum.Special : Special Function wrapper for HNum+* HNum.F       : Functional Programming Tools for HNum  ## Installation @@ -174,8 +175,9 @@ * Divide and Conquer Matrix Multiplication, Determinant, Inverse * Module CSV with DataFrame (read / write) * FuncTools+* Parallelize Matrix Arithmetics -### TODO (2018.06.13)+### TODO (2018.06.18)  * DSL Documentation by LaTeX (Developing)-* More Statistical Tools+* More Statistical Tools (Like Normal Distribution)
src/HNum/CSV.hs view
@@ -9,6 +9,8 @@ module HNum.CSV where  import           HNum.Vector+import           Data.List                      ( intercalate )+import           Control.Parallel  ----------------------------------------------- -- Declaration@@ -58,19 +60,22 @@   writeCSV :: Show a => String -> f a -> IO ()  instance Writable Vector where-  toString v = foldr (\x y -> x ++ "\n" ++ y) "" (show <$> v)+  toString v = intercalate "\n" (toList $ show <$> v)   writeCSV title v = writeFile title (toString v)  instance Writable Matrix where-  toString m = foldr ((\x y -> x ++ "\n" ++ y) . cm) "" m1+  toString m = m1 `seq` m2 `seq` intercalate "\n" m2     where m1 = matForm (show <$> m)+          m2 = map (intercalate ",") m1   writeCSV title m = writeFile title (toString m)  instance Writable DataFrame where-  toString (DataFrame h m) = h' ++ "\n" ++ m'-    where h' = cm h-          m' = toString (transpose m)-  writeCSV title df = writeFile title (toString df)+  toString (DataFrame h m) = h' `par` t' `pseq` m' `pseq` h' ++ "\n" ++ m'+    where h' = intercalate "," h+          t' = transpose m+          m' = toString t'+  writeCSV title df = df' `seq` writeFile title df'+    where df' = toString df  ----------------------------------------------- -- Read from CSV@@ -87,17 +92,12 @@ ----------------------------------------------- -- Backend Function -------------------------------------------------- | For Convenient -cm :: [String] -> String-cm [] = []-cm (x : xs) | null xs   = x-            | otherwise = x ++ "," ++ cm xs- -- | Split With Seperator splitWith :: Char -> String -> [String] splitWith _ [] = []-splitWith sep str | null temp'' = [temp]-                  | otherwise   = temp : splitWith sep temp'+splitWith sep str+  | null temp'' = [temp]+  | otherwise = temp `par` temp'' `pseq` temp' `pseq` temp : splitWith sep temp'  where   temp   = takeWhile (/= sep) str   temp'' = dropWhile (/= sep) str@@ -106,8 +106,9 @@ -- | Remove Quotation Symbol rmQuot :: String -> String rmQuot [] = []-rmQuot x | null temp = clean-         | otherwise = clean ++ rmQuot clean'+rmQuot x+  | null temp = clean+  | otherwise = clean `par` temp `pseq` clean' `pseq` clean ++ rmQuot clean'  where   clean  = takeWhile (/= '"') x   temp   = dropWhile (/= '"') x
src/HNum/F.hs view
@@ -1,7 +1,14 @@+{- +Module      : HNum.F+Description : Missing Functional Programming tools for HNumeric+CopyRight   : (c) Tae Geun Kim, 2018+License     : BSD3+Maintainer  : edeftg@gmail.com+Stability   : Experimental+-} module HNum.F where -import           HNum.Vector-import           HNum.CSV+import           Data.Functor                   ( )  -- | Functional Programming Tools for HNum Object class Functor f => FuncTools f where@@ -21,24 +28,4 @@   hdrop :: Int -> f a -> f a   -- | Like dropWhile   hdropWhile :: (a -> Bool) -> f a -> f a--instance FuncTools Vector where-  hflat f = f . toList-  hlift f = vec . f . toList-  hmap = hlift . map-  hfilter = hlift . filter-  htake n = hlift (take n)-  htakeWhile f = hlift (takeWhile f)-  hdrop n = hlift (drop n)-  hdropWhile f = hlift (dropWhile f)--instance FuncTools Matrix where-  hflat = undefined-  hlift f = matrix . map f . matForm-  hmap = hlift . map-  hfilter = hlift . filter-  htake n = hlift (take n)-  htakeWhile f = hlift (takeWhile f)-  hdrop n = hlift (drop n)-  hdropWhile f = hlift (dropWhile f) 
+ src/HNum/Special.hs view
@@ -0,0 +1,16 @@+module HNum.Special where++import           System.Random+import qualified Numeric.SpecFunctions         as SF+import           HNum.Vector+import           HNum.F++class FuncTools f => SpecialFunc f where+  erf :: Real a => f a -> f Double+  invErf :: Real a => f a -> f Double++instance SpecialFunc Vector where+  erf v = SF.erf . realToFrac <$> v+  invErf v = SF.invErf . realToFrac <$> v++
src/HNum/Stats.hs view
@@ -9,8 +9,6 @@ module HNum.Stats where  import           HNum.Vector-import           Data.Random.Normal-import           System.Random import           HNum.CSV  -- | To contain coefficients of linear regression.
src/HNum/Vector.hs view
@@ -1,5 +1,5 @@ {-|-Module      : HNumeric.Vector+Module      : HNum.Vector Description : Haskell Vector & Matrix & Linear Algebra Library to do machine learning CopyRight   : (c) Tae Geun Kim, 2018 License     : BSD3@@ -10,6 +10,8 @@  import           Data.Functor                   ( ) import           Control.Applicative            ( )+import           HNum.F+import           Control.Parallel  --------------------------------------------------- -- Vector@@ -76,14 +78,14 @@   -- | From List   fromList :: [a] -> m a   -- | Extract Element-  (!) :: m a -> Int -> a+  (.!) :: m a -> Int -> a   -- | Find Position of Element   findFirst :: Eq a => a -> m a -> Int  instance List Vector where   toList (Vector xs) = xs   fromList = Vector-  v ! n = toList v !! n+  v .! n = toList v !! n   findFirst n v | n `notElem` v = error "Not element!"                 | otherwise     = snd $ head $ dropWhile (\x -> fst x /= n) idx     where idx = zip (toList v) [0..]@@ -115,26 +117,30 @@     | r*c /= length v = error "Matrix Dimension mismatch!"     | b = ctake c v     | otherwise = dtake c v-      where ctake :: Int -> [a] -> [[a]]-            ctake _ [] = []-            ctake n m = take n m : ctake n (drop n m)-            dtake :: Int -> [a] -> [[a]]-            dtake _ [] = []-            dtake n m = [ptake n m r | r <- [0..(length m `div` n - 1)]]-            ptake n v r = [v !! x | x <- idx v, x `mod` (length v `div` n) == r]-            idx v = take (length v) [0..]+    where ctake _ [] = []+          ctake n m = let tnm = take n m+                          dnm = drop n m in tnm `par` dnm `pseq` tnm : ctake n dnm+          dtake _ [] = []+          dtake n m = [ptake n m r | r <- [0..(length m `div` n - 1)]]+          ptake n v r = let idxv = idx v in idxv `seq` [v !! x | x <- idxv, x `mod` (length v `div` n) == r]+          idx v = take (length v) [0..]   formMat [] = Matrix (Vector []) 0 0 True-  formMat xs = Matrix (Vector (concat xs)) (length xs) (length (head xs)) True+  formMat xs = cxs `par` lxs `pseq` Matrix (Vector cxs) lxs (length (head xs)) True+    where cxs = concat xs+          lxs = length xs  instance Show a => Show (Matrix a) where   show m = "Matrix " ++ show (matForm m)  instance Functor Matrix where-  fmap f mat = mat { val = fmap f (val mat) }+  fmap f mat = vm `seq` mat { val = fmap f vm }+    where vm = val mat  instance Applicative Matrix where   pure a = matrix []-  mf <*> mx = mx { val = val mf <*> val mx }+  mf <*> mx = vmf `par` vmx `pseq` mx { val = vmf <*> vmx }+    where vmf = val mf+          vmx = val mx  instance Num a => Num (Matrix a) where   negate m = negate <$> m@@ -175,6 +181,29 @@   foldl f z (Matrix (Vector xs) _ _ _) = foldl f z xs  ---------------------------------------------------+-- FuncTools+---------------------------------------------------+instance FuncTools Vector where+      hflat f = f . toList+      hlift f = vec . f . toList+      hmap = hlift . map+      hfilter = hlift . filter+      htake n = hlift (take n)+      htakeWhile f = hlift (takeWhile f)+      hdrop n = hlift (drop n)+      hdropWhile f = hlift (dropWhile f)++instance FuncTools Matrix where+      hflat = undefined+      hlift f = matrix . map f . matForm+      hmap = hlift . map+      hfilter = hlift . filter+      htake n = hlift (take n)+      htakeWhile f = hlift (takeWhile f)+      hdrop n = hlift (drop n)+      hdropWhile f = hlift (dropWhile f)++--------------------------------------------------- -- Type Conversion --------------------------------------------------- -- | Syntactic Sugar of read of functor@@ -244,17 +273,28 @@  instance MatOps Matrix where   m %*% n | col m /= row n = error "Can't Multiply - Dimension mismatch!"-          | otherwise      = matrix $ matForm m %-*-% matForm n-  m %/% n = m %*% inv n+          | otherwise      = mfm `par` mfn `pseq` matrix $ mfm %-*-% mfn+          where mfm = matForm m+                mfn = matForm n+  m %/% n = invn `seq` m %*% invn+    where invn = inv n   det m | col m /= row m = error "Can't calculate determinant of non-square matrix"         | otherwise = detMat (matForm m)   inv m | col m /= row m = error "Can't calculate inverse of non-square matrix"-        | otherwise = (matrix . invMat . matForm) m-  transpose m = m {row = col m, col = row m, byRow = not (byRow m)}+        | otherwise = mfm `seq` invM `seq` matrix invM+        where mfm = matForm m+              invM = invMat mfm+  transpose m = cm `par` rm `par` bm `pseq` m {row = col m, col = row m, byRow = not (byRow m)}+    where cm = col m+          rm = row m+          bm = byRow m  -- |Block Partitioning bp :: Int -> Matrix a -> Matrix a-bp n m = matrix $ bpMat n (matForm m)+bp n m = mfm `seq` bpm `seq` matrix bpm+ where+  mfm = matForm m+  bpm = bpMat n mfm  --------------------------------------------------- -- Concatenate@@ -264,35 +304,48 @@   vcat :: f a -> f a -> Matrix a  instance Concatable Vector where-  hcat v w = fromList (toList v ++ toList w)-  vcat v w = matrix (toList v : [toList w])+  hcat v w = tlv `par` tlw `pseq` fromList (tlv ++ tlw)+    where tlv = toList v+          tlw = toList w+  vcat v w = tlv `par` tlw `pseq` matrix tlm+    where tlv = toList v+          tlw = [toList w]+          tlm = tlv : tlw  instance Concatable Matrix where-  hcat m n | row m == row n = matrix (zipWith (++) mf nf)+  hcat m n | row m == row n = mf `par` nf `pseq` matrix (zipWith (++) mf nf)            | otherwise = error "Can't concatenate matrices horizontally which have different row"            where mf = matForm m                  nf = matForm n-  vcat m n | col m == col n = m {val = hcat (val m) (val n), row = row m + row n}+  vcat m n | col m == col n = vm `par` vn `pseq` hmn `par` rm `par` rn `pseq` m {val = hmn, row = rm + rn}            | otherwise = error "Can't concatenate matrices vertically which have different col"+           where vm = val m+                 vn = val n+                 hmn = hcat vm vn+                 rm = row m+                 rn = row n  -- |(.:) inserts vector to head of matrix. (.:) :: Vector a -> Matrix a -> Matrix a-v .: m | length v == col m = matrix (toList v : matForm m)+v .: m | length v == col m = tv `par` mfm `pseq` matrix (tv : mfm)        | otherwise         = error "Can't insert length(Vector) /= col(Matrix)"+ where+  tv  = toList v+  mfm = matForm m  --------------------------------------------------- -- Sort --------------------------------------------------- -- | Quick Sort qsort :: Ord a => Vector a -> Vector a-qsort (Vector []) = vec []-qsort (Vector (x : xs)) =-  (qsort . vec) [ y | y <- xs, y <= x ] `hcat` vec [x] `hcat` (qsort . vec)-    [ y | y <- xs, y > x ]---- | Merge Sort---msort :: Ord a => Vector a -> Vector a---msort +qsort (Vector []      ) = vec []+qsort (Vector (x : xs)) = qsv1 `par` qsv2 `par` vx `pseq` hv1 `pseq` hv2+ where+  qsv1 = (qsort . vec) [ y | y <- xs, y <= x ]+  qsv2 = (qsort . vec) [ y | y <- xs, y > x ]+  vx   = vec [x]+  hv1  = hcat qsv1 vx+  hv2  = hcat hv1 qsv2  --------------------------------------------------- -- Backend Functions (Do not Understand)@@ -361,7 +414,23 @@ _     %-*-% [[]]  = [[]] [[] ] %-*-% _     = [[]] [[x]] %-*-% [[y]] = [[x * y]]-m     %-*-% n     = zipWith (++) a11 a12 ++ zipWith (++) a21 a22+m %-*-% n =+  m11+    `par`  m12+    `par`  m21+    `par`  m22+    `par`  n11+    `par`  n12+    `par`  n21+    `par`  n22+    `pseq` a11+    `par`  a12+    `par`  a21+    `par`  a22+    `pseq` b1+    `par`  b2+    `pseq` b1+    ++     b2  where   (m11, n11) = (bpMat 1 m, bpMat 1 n)   (m12, n12) = (bpMat 2 m, bpMat 2 n)@@ -371,6 +440,8 @@   a12        = (m11 %-*-% n12) %-+-% (m12 %-*-% n22)   a21        = (m21 %-*-% n11) %-+-% (m22 %-*-% n21)   a22        = (m21 %-*-% n12) %-+-% (m22 %-*-% n22)+  b1         = zipWith (++) a11 a12+  b2         = zipWith (++) a21 a22  zerosVec :: Int -> [Int] zerosVec n = take n [0, 0 ..]@@ -380,7 +451,10 @@  -- Position -> Length  basisVec :: Int -> Int -> [Int]-basisVec n m = zerosVec n ++ [1] ++ zerosVec (m - n - 1)+basisVec n m = zvn `par` zvm `pseq` zvn ++ [1] ++ zvm+ where+  zvn = zerosVec n+  zvm = zerosVec (m - n - 1)  permMat :: Int -> Int -> [[a]] -> [[Int]] permMat i j m@@ -425,9 +499,23 @@ detMat :: (Eq a, Fractional a) => [[a]] -> a detMat [[x]] = x detMat m-  | l == 2    = detMat m11 * detMat m22 - detMat m12 * detMat m21-  | d00 == 0  = (-1) ^ (l - 1) * detMat (cycleMat m)-  | otherwise = (detMat m11 * detMat m22 - detMat m12 * detMat m21) / detMat m00+  | l == 2+  = detMat m11 * detMat m22 - detMat m12 * detMat m21+  | d00 == 0+  = determinant m+  | otherwise+  = m11+    `par`  m12+    `par`  m21+    `par`  m22+    `par`  m00+    `pseq` d00+    `par`  d11+    `par`  d12+    `par`  d21+    `par`  d22+    `pseq` (d11 * d22 - d12 * d21)+    /      d00  where   l   = length m   m11 = bpMat' 1 m@@ -436,6 +524,10 @@   m22 = bpMat' 4 m   m00 = bpMat' 0 m   d00 = detMat m00+  d11 = detMat m11+  d22 = detMat m22+  d12 = detMat m12+  d21 = detMat m21  -- | Inverse for Double List - Order ~ n * 2^n invMat :: (Eq a, Fractional a) => [[a]] -> [[a]]@@ -448,7 +540,21 @@     $  zipWith (++) m22          (negMap m12)     ++ zipWith (++) (negMap m21) m11   | otherwise-  = zipWith (++) a11 a12 ++ zipWith (++) a21 a22+  = m11+    `par`  m12+    `par`  m21+    `par`  m22+    `pseq` a00+    `pseq` s+    `pseq` s00+    `pseq` a11+    `par`  a12+    `par`  a21+    `par`  a22+    `pseq` b1+    `par`  b2+    `pseq` b1+    ++     b2  where   m11 = bpMat 1 m   m12 = bpMat 2 m@@ -461,9 +567,42 @@   a12 = negMap a00 %-*-% m12 %-*-% s00   a21 = negMap s00 %-*-% m21 %-*-% a00   a22 = s00+  b1  = zipWith (++) a11 a12+  b2  = zipWith (++) a21 a22  -- | Find First  fd :: Eq a => a -> [a] -> Int fd n v | n `notElem` v = error "Not element!"        | otherwise     = snd $ head $ dropWhile (\x -> fst x /= n) idx   where idx = zip v [0 ..]+++-------------------------------------------------------------+-- Rosetta Stone+-------------------------------------------------------------+sPermutations :: [a] -> [([a], Int)]+sPermutations = flip zip (cycle [1, -1]) . foldl aux [[]]+ where+  aux items x = do+    (f, item) <- zip (cycle [reverse, id]) items+    f (insertEv x item)+  insertEv x []         = [[x]]+  insertEv x l@(y : ys) = (x : l) : ((y :) <$>) (insertEv x ys)++elemPos :: [[a]] -> Int -> Int -> a+elemPos ms i j = (ms !! i) !! j++prod :: Num a => ([[a]] -> Int -> Int -> a) -> [[a]] -> [Int] -> a+prod f ms = product . zipWith (f ms) [0 ..]++sDeterminant+  :: Num a => ([[a]] -> Int -> Int -> a) -> [[a]] -> [([Int], Int)] -> a+sDeterminant f ms = sum . fmap (\(is, s) -> fromIntegral s * prod f ms is)++determinant :: Num a => [[a]] -> a+determinant ms =+  sDeterminant elemPos ms . sPermutations $ [0 .. pred . length $ ms]++permanent :: Num a => [[a]] -> a+permanent ms =+  sum . fmap (prod elemPos ms . fst) . sPermutations $ [0 .. pred . length $ ms]