packages feed

bed-and-breakfast 0.4 → 0.4.1

raw patch · 3 files changed

+137/−55 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Numeric.Matrix: instance MatrixElement e => NFData (Matrix e)
+ Numeric.Matrix: instance (MatrixElement e, NFData e) => NFData (Matrix e)
+ Numeric.Matrix: instance MatrixElement Int32
+ Numeric.Matrix: instance MatrixElement Int64

Files

bed-and-breakfast.cabal view
@@ -1,5 +1,5 @@ Name:           bed-and-breakfast-Version:        0.4+Version:        0.4.1 Synopsis:       Efficient Matrix operations in 100% Haskell. Description:    Efficient Matrix operations in 100% Haskell.                 .@@ -52,6 +52,11 @@                 [@v0.4@] Fixed a bug regarding @empty@ and @fromList@.                     Use unsafe operations where it is safe for speed.                     Added RULES. Added an instance for binary.+                .+                [@v0.4.1@] The unsafe operations used in v0.4 turned out+                    to fatally fail on certain platforms. Revoked this+                    change. Thanks to Marcin Fatyga for pointing at the+                    issue.   License:        MIT
quickcheck-tests.hs view
@@ -1,5 +1,8 @@ {-# LANGUAGE Haskell2010, TemplateHaskell #-} +import Prelude+import qualified Prelude as P+ import Control.Monad  import Numeric.Matrix@@ -9,7 +12,11 @@  import System.Exit +import Data.Ratio+import Data.Int+import Data.Word + dim :: Num a => a dim = 6 @@ -18,12 +25,40 @@     arbitrary = sequence (replicate dim (vector dim)) >>= return . fromList  +basic m = m + m == scale m 2 && m * m * m == m ^ 3++prop_zero :: Word8 -> Bool+prop_zero = isZero . (zero :: Int -> Matrix Double) . fromIntegral++prop_sum_trace :: Word8 -> Bool+prop_sum_trace n = ((== nd) . P.sum . trace . (unit :: Int -> Matrix Double) . fromIntegral) n'+  where n' = n + 1+        nd = fromIntegral n'++prop_basic_integer :: Matrix Integer -> Bool+prop_basic_integer = basic++prop_basic_int :: Matrix Int -> Bool+prop_basic_int = basic++prop_basic_float :: Matrix Float -> Bool+prop_basic_float = basic++prop_basic_double :: Matrix Double -> Bool+prop_basic_double = basic++prop_basic_rational :: Matrix Rational -> Bool+prop_basic_rational = basic++prop_zero_det_double :: Matrix Double -> Bool+prop_zero_det_double m1 = let m1' = inv m1 in case m1' of (Just _) -> det m1 /= 0; _ -> det m1 == 0++prop_zero_det_rational :: Matrix Rational -> Bool+prop_zero_det_rational m1 = let m1' = inv m1 in case m1' of (Just _) -> det m1 /= 0; _ -> det m1 == 0+ prop_plus_commutative :: Matrix Double -> Matrix Double -> Bool prop_plus_commutative m1 m2 = m1 + m2 == m2 + m1 -prop_zero_det :: Matrix Rational -> Bool-prop_zero_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 @@ -39,11 +74,8 @@ prop_inv_twice :: Matrix Rational -> Bool prop_inv_twice m1 = let m1' = inv m1 in case m1' of (Just m1') -> inv m1' == Just m1; _ -> True - main = do-     success <- $(quickCheckAll)-         (if success then exitSuccess else exitFailure)  
src/Numeric/Matrix.hs view
@@ -71,7 +71,6 @@ import Data.Array.MArray import Data.Array.Unboxed import Data.Array.ST-import Data.Array.Base (unsafeRead, unsafeWrite) import Data.STRef import Data.Binary @@ -136,9 +135,16 @@ -- See @encode@ and @decode@. data family Matrix e + data instance Matrix Int     = IntMatrix !Int !Int (Array Int (UArray Int Int)) +data instance Matrix Int32+    = Int32Matrix !Int !Int (Array Int (UArray Int Int32))++data instance Matrix Int64+    = Int64Matrix !Int !Int (Array Int (UArray Int Int64))+ data instance Matrix Float     = FloatMatrix !Int !Int (Array Int (UArray Int Float)) @@ -189,8 +195,8 @@             = allWithIndex (\ix e -> m `at` ix == e) n         | otherwise = False -instance (MatrixElement e) => NFData (Matrix e) where-    rnf matrix = matrix `deepseq` ()+instance (MatrixElement e, NFData e) => NFData (Matrix e) where+    rnf matrix = map (\x -> x `deepseq` x) matrix `deepseq` ()  instance (MatrixElement e, Binary e) => Binary (Matrix e) where     @@ -378,9 +384,23 @@     -- > dimensions empty == (0, 0)     empty :: Matrix e +    -- | Subtract a matrix from another.     minus :: Matrix e -> Matrix e -> Matrix e++    -- | Add two matrices.+    --+    -- You may also use the 'Num' instance for matrices,+    -- i.e. @matrix1 + matrix2@ will work, too.     plus  :: Matrix e -> Matrix e -> Matrix e++    -- | Multiply two matrices /O(n^3)/.+    --+    -- You may also use the 'Num' instance for matrices,+    -- i.e. @matrix1 * matrix2@ will work, too.     times :: Matrix e -> Matrix e -> Matrix e++    -- | Compute the inverse of a matrix. Returns @Nothing@+    -- if the matrix is not invertible.     inv   :: Matrix e -> Maybe (Matrix e)      -- | Applies Bareiss multistep integer-preserving@@ -486,6 +506,30 @@     det        (IntMatrix m n arr) = if m /= n then 0 else runST (_det thawsUnboxed arr)     rank       (IntMatrix _ _ arr) = runST (_rank thawsBoxed arr) +instance MatrixElement Int32 where+    matrix d g = runST (_matrix Int32Matrix arrayST arraySTU d g)+    fromList = _fromList Int32Matrix++    at         (Int32Matrix _ _ arr) = _at arr+    dimensions (Int32Matrix m n _) = (m, n)+    row i      (Int32Matrix _ _ arr) = _row i arr+    col j      (Int32Matrix _ _ arr) = _col j arr+    toList     (Int32Matrix _ _ arr) = _toList arr+    det        (Int32Matrix m n arr) = if m /= n then 0 else runST (_det thawsUnboxed arr)+    rank       (Int32Matrix _ _ arr) = runST (_rank thawsBoxed arr)++instance MatrixElement Int64 where+    matrix d g = runST (_matrix Int64Matrix arrayST arraySTU d g)+    fromList = _fromList Int64Matrix++    at         (Int64Matrix _ _ arr) = _at arr+    dimensions (Int64Matrix m n _) = (m, n)+    row i      (Int64Matrix _ _ arr) = _row i arr+    col j      (Int64Matrix _ _ arr) = _col j arr+    toList     (Int64Matrix _ _ arr) = _toList arr+    det        (Int64Matrix m n arr) = if m /= n then 0 else runST (_det thawsUnboxed arr)+    rank       (Int64Matrix _ _ arr) = runST (_rank thawsBoxed arr)+ instance MatrixElement Integer where     matrix d g = runST (_matrix IntegerMatrix arrayST arrayST d g)     fromList   = _fromList IntegerMatrix@@ -530,7 +574,6 @@  instance (Show a, Integral a) => MatrixElement (Ratio a) where     matrix d g = runST (_matrix RatioMatrix arrayST arrayST d g)---    matrix d g = unsafePerformIO (_matrixIO RatioMatrix arrayIO arrayIO d g)     fromList   = _fromList RatioMatrix      at         (RatioMatrix _ _ arr) = _at arr@@ -632,7 +675,7 @@  read :: (MArray a1 b m, MArray a (a1 Int b) m) =>                        a Int (a1 Int b) -> Int -> Int -> m b-read a i j = unsafeRead a i >>= flip unsafeRead j+read a i j = readArray a i >>= flip readArray j   _inv :: (IArray a e, MArray (u s) e (ST s), Fractional e, Ord e, Show e)@@ -644,9 +687,9 @@         n = 2*m          swap a i j = do-            tmp <- unsafeRead a i-            unsafeRead a j >>= unsafeWrite a i-            unsafeWrite a j tmp+            tmp <- readArray a i+            readArray a j >>= writeArray a i+            writeArray a j tmp      okay <- newSTRef True @@ -662,37 +705,37 @@             swap a iPivot k              forM_ [k+1..m] $ \i -> do-                a_i <- unsafeRead a i-                a_k <- unsafeRead a k+                a_i <- readArray a i+                a_k <- readArray a k                 forM_ [k+1..n] $ \j -> do-                    a_ij <- unsafeRead a_i j-                    a_kj <- unsafeRead a_k j-                    a_ik <- unsafeRead a_i k-                    unsafeWrite a_i j (a_ij - a_kj * (a_ik / p))-                unsafeWrite a_i k 0+                    a_ij <- readArray a_i j+                    a_kj <- readArray a_k j+                    a_ik <- readArray a_i k+                    writeArray a_i j (a_ij - a_kj * (a_ik / p))+                writeArray a_i k 0      invertible <- readSTRef okay      if invertible then       do         forM_ [ m - v | v <- [0..m-1] ] $ \i -> do-            a_i <- unsafeRead a i-            p   <- unsafeRead a_i i-            unsafeWrite a_i i 1+            a_i <- readArray a i+            p   <- readArray a_i i+            writeArray a_i i 1             forM_ [i+1..n] $ \j -> do-                unsafeRead a_i j >>= unsafeWrite a_i j . (/ p)+                readArray a_i j >>= writeArray a_i j . (/ p)              unless (i == m) $ do                 forM_ [i+1..m] $ \k -> do-                    a_k <- unsafeRead a k-                    p   <- unsafeRead a_i k+                    a_k <- readArray a k+                    p   <- readArray a_i k                      forM_ [k..n] $ \j -> do-                        a_ij <- unsafeRead a_i j-                        a_kj <- unsafeRead a_k j-                        unsafeWrite a_i j (a_ij - p * a_kj)+                        a_ij <- readArray a_i j+                        a_kj <- readArray a_k j+                        writeArray a_i j (a_ij - p * a_kj) -        mapM (\i -> unsafeRead a i >>= getElems+        mapM (\i -> readArray a i >>= getElems                         >>= return . listArray (1, m) . drop m) [1..m]             >>= return . Just . listArray (1, m) @@ -707,9 +750,9 @@         n = snd $ bounds (mat ! 1)          swap a i j = do-            tmp <- unsafeRead a i-            unsafeRead a j >>= unsafeWrite a i-            unsafeWrite a j tmp+            tmp <- readArray a i+            readArray a j >>= writeArray a i+            writeArray a j tmp      a <- thaws mat >>= arrays @@ -726,17 +769,17 @@             let ix = fromJust switchRow + pivotRow             when (pivotRow /= ix) (swap a pivotRow ix) -            a_p   <- unsafeRead a k-            pivot <- unsafeRead a_p k+            a_p   <- readArray a k+            pivot <- readArray a_p k             prev  <- readSTRef prevR                          forM_ [pivotRow+1..m] $ \i -> do-                a_i <- unsafeRead a i+                a_i <- readArray a i                 forM_ [k+1..n] $ \j -> do-                    a_ij <- unsafeRead a_i j-                    a_ik <- unsafeRead a_i k-                    a_pj <- unsafeRead a_p j-                    unsafeWrite a_i j ((pivot * a_ij - a_ik * a_pj)+                    a_ij <- readArray a_i j+                    a_ik <- readArray a_i k+                    a_pj <- readArray a_p j+                    writeArray a_i j ((pivot * a_ij - a_ik * a_pj)                                         `divide` prev)              writeSTRef ixPivot (pivotRow + 1)@@ -774,9 +817,9 @@                 when (not $ null sf) $ do                     let sw = head sf -                    row <- unsafeRead a sw-                    unsafeRead a k >>= unsafeWrite a sw-                    unsafeWrite 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@@ -787,21 +830,23 @@             unless (sign' == 0) $ do                 pivot' <- readSTRef pivotR                 forM_ [(k+1)..size] $ \i -> do-                    a_i <- unsafeRead a i+                    a_i <- readArray a i                     forM [(k+1)..size] $ \j -> do-                        a_ij <- unsafeRead a_i j-                        a_ik <- unsafeRead a_i k+                        a_ij <- readArray a_i j+                        a_ik <- readArray a_i k                         a_kj <- read a k j-                        unsafeWrite a_i j ((pivot' * a_ij - a_ik * a_kj) `divide` prev)+                        writeArray a_i j ((pivot' * a_ij - a_ik * a_kj) `divide` prev)      liftM2 (*) (readSTRef pivotR) (readSTRef signR)   _mult :: MatrixElement e => Matrix e -> Matrix e -> Matrix e-_mult a b = let rowsA = numRows a-                rowsB = numRows b-                colsB = numCols b-            in  matrix (rowsA, colsB) (\(i,j) -> L.foldl' (+) 0 [a `at` (i, k) * b `at` (k, j) | k <- [1..rowsB]])+_mult a b =+    let rowsA = numRows a+        rowsB = numRows b+        colsB = numCols b+        gen i j = L.foldl' (+) 0 [a `at` (i, k) * b `at` (k, j) | k <- [1..rowsB]]+    in  matrix (rowsA, colsB) (uncurry gen)   _matrix :: (IArray a1 (u Int e), IArray u e,@@ -818,8 +863,8 @@     forM_ [1..m] $ \i -> do         cols <- newArrayU (1, n) 0         forM_ [1..n] $ \j -> do-            unsafeWrite cols j (g (i,j))-        U.unsafeFreeze cols >>= unsafeWrite rows i+            writeArray cols j (g (i,j))+        U.unsafeFreeze cols >>= writeArray rows i     U.unsafeFreeze rows >>= return . c m n