packages feed

bed-and-breakfast 0.2.3 → 0.3

raw patch · 3 files changed

+102/−28 lines, 3 filesdep +QuickCheckdep +bed-and-breakfastPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, bed-and-breakfast

API changes (from Hackage documentation)

- Numeric.Matrix: class (Eq e, Num e) => MatrixElement e where unit n = fromList [[if i == j then 1 else 0 | j <- [1 .. n]] | i <- [1 .. n]] zero n = matrix (n, n) (const 0) empty = fromList [] diag xs = matrix (n, n) (\ (i, j) -> if i == j then xs !! (i - 1) else 0) where n = length xs select p m = [at m (i, j) | i <- [1 .. numRows m], j <- [1 .. numCols m], p (i, j)] at m (i, j) = ((!! j) . (!! i) . toList) m row i m = ((!! (i - 1)) . toList) m col i m = (row i . transpose) m numRows = fst . dimensions numCols = snd . dimensions dimensions m = case toList m of { [] -> (0, 0) (x : xs) -> (length xs + 1, length x) } adjugate = transpose . cofactors transpose = fromList . transpose . toList trace = select (uncurry (==)) inv _ = Nothing minorMatrix m (i, j) = matrix (numRows m - 1, numCols m - 1) $ \ (i', j') -> m `at` (if i' >= i then i' + 1 else i', if j' >= j then j' + 1 else j') minor m = det . minorMatrix m cofactors m = matrix (dimensions m) $ \ (i, j) -> fromIntegral ((- 1 :: Int) ^ (i + j)) * minor m (i, j) map f = mapWithIndex (const f) all f = allWithIndex (const f) any f = anyWithIndex (const f) mapWithIndex f m = matrix (dimensions m) (\ x -> f x (m `at` x)) allWithIndex f m = all id [f (i, j) (m `at` (i, j)) | i <- [1 .. numRows m], j <- [1 .. numCols m]] anyWithIndex f m = any id [f (i, j) (m `at` (i, j)) | i <- [1 .. numRows m], j <- [1 .. numCols m]] a plus b | dimensions a /= dimensions b = error "Matrix.plus: dimensions don't match." | otherwise = matrix (dimensions a) (\ x -> a `at` x + b `at` x) a minus b | dimensions a /= dimensions b = error "Matrix.minus: dimensions don't match." | otherwise = matrix (dimensions a) (\ x -> a `at` x - b `at` x) a times b | numRows a /= numCols b = error "Matrix.times: `numRows a' and `numCols b' don't match." | otherwise = fromList [[row i a `dotProd` col j b | j <- [1 .. numCols b]] | i <- [1 .. numRows a]]
+ Numeric.Matrix: class (Eq e, Num e) => MatrixElement e where unit n = fromList [[if i == j then 1 else 0 | j <- [1 .. n]] | i <- [1 .. n]] zero n = matrix (n, n) (const 0) empty = fromList [] diag xs = matrix (n, n) (\ (i, j) -> if i == j then xs !! (i - 1) else 0) where n = length xs select p m = [at m (i, j) | i <- [1 .. numRows m], j <- [1 .. numCols m], p (i, j)] at m (i, j) = ((!! j) . (!! i) . toList) m row i m = ((!! (i - 1)) . toList) m col i m = (row i . transpose) m numRows = fst . dimensions numCols = snd . dimensions dimensions m = case toList m of { [] -> (0, 0) (x : xs) -> (length xs + 1, length x) } adjugate = transpose . cofactors transpose m = matrix (dimensions m) (\ (i, j) -> m `at` (j, i)) trace = select (uncurry (==)) inv _ = Nothing minorMatrix m (i, j) = matrix (numRows m - 1, numCols m - 1) $ \ (i', j') -> m `at` (if i' >= i then i' + 1 else i', if j' >= j then j' + 1 else j') minor m = det . minorMatrix m cofactors m = matrix (dimensions m) $ \ (i, j) -> fromIntegral ((- 1 :: Int) ^ (i + j)) * minor m (i, j) map f = mapWithIndex (const f) all f = allWithIndex (const f) any f = anyWithIndex (const f) mapWithIndex f m = matrix (dimensions m) (\ x -> f x (m `at` x)) allWithIndex f m = all id [f (i, j) (m `at` (i, j)) | i <- [1 .. numRows m], j <- [1 .. numCols m]] anyWithIndex f m = any id [f (i, j) (m `at` (i, j)) | i <- [1 .. numRows m], j <- [1 .. numCols m]] a plus b | dimensions a /= dimensions b = error "Matrix.plus: dimensions don't match." | otherwise = matrix (dimensions a) (\ x -> a `at` x + b `at` x) a minus b | dimensions a /= dimensions b = error "Matrix.minus: dimensions don't match." | otherwise = matrix (dimensions a) (\ x -> a `at` x - b `at` x) a times b | numRows a /= numCols b = error "Matrix.times: `numRows a' and `numCols b' don't match." | otherwise = fromList [[row i a `dotProd` col j b | j <- [1 .. numCols b]] | i <- [1 .. numRows a]]

Files

bed-and-breakfast.cabal view
@@ -1,5 +1,5 @@ Name:           bed-and-breakfast-Version:        0.2.3+Version:        0.3 Synopsis:       Efficient Matrix operations in 100% Haskell. Description:    Efficient Matrix operations in 100% Haskell.                 .@@ -37,7 +37,10 @@                 .                 [@v0.2.3@] Added 'Read' instance for @Matrix@.                     Improved on documentation.-+                .+                [@v0.3@] Added a QuickCheck test suite, fixed a bug in @det@+                    (det would crash for singular matrices, where it should+                    return 0; it does so no).  License:        MIT License-File:   LICENSE@@ -60,4 +63,10 @@                         array >= 0.4     Hs-Source-Dirs:     src +Test-Suite quickcheck+    type:           exitcode-stdio-1.0+    main-is:        quick-check-tests.hs+    build-depends:  base >= 4.5 && < 5,+                    bed-and-breakfast == 0.3,+                    QuickCheck >= 2.4.2 
+ quick-check-tests.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE Haskell2010, TemplateHaskell #-}++import Control.Monad++import Numeric.Matrix++import Test.QuickCheck+import Test.QuickCheck.All++import System.Exit+++dim :: Num a => a+dim = 4++instance (MatrixElement e, Arbitrary e) => Arbitrary (Matrix e) where++    arbitrary = sequence (replicate dim (vector dim)) >>= return . fromList+++prop_det :: Matrix Rational -> Bool+prop_det m1 = let m1' = inv m1 in case m1' of (Just _) -> det m1 /= 0; _ -> det m1 == 0++prop_inv :: Matrix Rational -> Bool+prop_inv m1 = let m1' = inv m1 in case m1' of (Just m1') -> m1' * m1 == unit dim; _ -> True++prop_rank :: Matrix Rational -> Bool+prop_rank m1 = let r = rank m1 in if r < dim then det m1 == 0 else r == dim+++main = do+    success <- $(quickCheckAll)+    +    (if success then exitSuccess else exitFailure)++
src/Numeric/Matrix.hs view
@@ -290,22 +290,48 @@      -- | The dimensions of a given matrix.     dimensions :: Matrix e -> (Int, Int)++    -- | The number of rows in the given matrix.     numRows :: Matrix e -> Int++    -- | The number of columns in the given matrix.     numCols :: Matrix e -> Int       -- | Builds a matrix from a list of lists.     --+    -- The innermost lists represent the rows. This function will create a m-n-matrix,+    -- where m is the number of rows, which is the minimum length of the row lists+    -- and n is the number of columns, i.e. the length of the outer list.+    --     -- > fromList [[1,2,3],[2,1,3],[3,2,1]] :: Matrix Rational     fromList :: [[e]] -> Matrix e     toList   :: Matrix e -> [[e]]      -- | An identity square matrix of the given size.+    --+    -- >> unit 4+    -- 1 0 0 0+    -- 0 1 0 0+    -- 0 0 1 0+    -- 0 0 0 1     unit  :: Int -> Matrix e      -- | A square matrix of the given size consisting of all zeros.+    -- +    -- >> zero 2+    -- 0 0+    -- 0 0     zero  :: Int -> Matrix e +    -- | A square matrix which trace is the given list, all other components+    -- set to zero.+    --+    -- >> diag [1,4,7,9]+    -- 1 0 0 0+    -- 0 4 0 0+    -- 0 0 7 0+    -- 0 0 0 9     diag  :: [e] -> Matrix e      -- | Check whether the matrix is the empty matrix.@@ -318,9 +344,6 @@     times :: Matrix e -> Matrix e -> Matrix e     inv   :: Matrix e -> Maybe (Matrix e) ---    adjugate  :: Matrix e -> Matrix e---    cofactors :: Matrix e -> Matrix e ; cofactors = undefined-     -- | Applies Bareiss multistep integer-preserving     -- algorithm for finding the determinant of a matrix.     -- Returns 0 if the matrix is not a square matrix.@@ -376,7 +399,7 @@                                     (x:xs) -> (length xs + 1, length x)      adjugate = transpose . cofactors-    transpose = fromList . L.transpose . toList+    transpose m = matrix (dimensions m) (\(i,j) -> m `at` (j,i))     trace = select (uncurry (==))     inv _ = Nothing @@ -703,34 +726,40 @@     pivotR <- newSTRef 1      flip mapM_ [1..size] $ \k -> do+        sign <- readSTRef signR+        unless (sign == 0) $ do -        prev  <- readSTRef pivotR-        pivot <- read a k k >>= tee (writeSTRef pivotR)+            prev  <- readSTRef pivotR+            pivot <- read a k k >>= tee (writeSTRef pivotR) -        when (pivot == 0) $ do-            s <- flip mapM [(k+1)..size] $ \r -> do-                a_rk <- read a r k-                if a_rk == 0 then return 0 else return r-            let sf = filter (>0) s+            when (pivot == 0) $ do+                s <- flip mapM [(k+1)..size] $ \r -> do+                    a_rk <- read a r k+                    if a_rk == 0 then return 0 else return r+                let sf = filter (>0) s -            when (not $ null sf) $ do-                let sw = head sf+                when (not $ null sf) $ do+                    let sw = head sf -                row <- readArray a sw-                readArray a k >>= writeArray a sw-                writeArray a k row+                    row <- readArray a sw+                    readArray a k >>= writeArray a sw+                    writeArray a k row -                read a k k >>= writeSTRef pivotR-                readSTRef signR >>= writeSTRef signR . negate+                    read a k k >>= writeSTRef pivotR+                    readSTRef signR >>= writeSTRef signR . negate -        pivot' <- readSTRef pivotR-        flip mapM [(k+1)..size] $ \i -> do-            a_i <- readArray a i-            flip mapM [(k+1)..size] $ \j -> do-                a_ij <- readArray a_i j-                a_ik <- readArray a_i k-                a_kj <- read a k j-                writeArray a_i j ((pivot' * a_ij - a_ik * a_kj) `divide` prev)+                when (null sf) (writeSTRef signR 0)++            sign' <- readSTRef signR+            unless (sign' == 0) $ do+                pivot' <- readSTRef pivotR+                flip mapM_ [(k+1)..size] $ \i -> do+                    a_i <- readArray a i+                    flip mapM [(k+1)..size] $ \j -> do+                        a_ij <- readArray a_i j+                        a_ik <- readArray a_i k+                        a_kj <- read a k j+                        writeArray a_i j ((pivot' * a_ij - a_ik * a_kj) `divide` prev)      liftM2 (*) (readSTRef pivotR) (readSTRef signR)