bed-and-breakfast 0.2 → 0.2.1
raw patch · 2 files changed
+82/−64 lines, 2 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Numeric.Matrix: adjugate :: (MatrixElement e, MatrixElement e) => Matrix e -> Matrix e
+ Numeric.Matrix: cofactors :: (MatrixElement e, MatrixElement e) => Matrix e -> Matrix e
+ Numeric.Matrix: minor :: (MatrixElement e, MatrixElement e) => Matrix e -> (Int, Int) -> e
+ Numeric.Matrix: minorMatrix :: (MatrixElement e, MatrixElement e) => Matrix e -> (Int, Int) -> Matrix e
- 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) } transpose = fromList . transpose . toList trace = select (uncurry (==)) inv _ = Nothing 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 = 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]]
Files
- bed-and-breakfast.cabal +6/−2
- src/Numeric/Matrix.hs +76/−62
bed-and-breakfast.cabal view
@@ -1,5 +1,5 @@ Name: bed-and-breakfast-Version: 0.2+Version: 0.2.1 Synopsis: Efficient Matrix operations in 100% Haskell. Description: Efficient Matrix operations in 100% Haskell. .@@ -27,7 +27,11 @@ [@v0.2@] A little bit more documentation. Also moved some functions (@isXXX@) away from the type class @MatrixElement@. Properly flagged the package as experimental (was- improperly copied as @stable@, copied form a template).+ improperly marked as @stable@, copied form a+ template).+ .+ [@v0.2.1@] Added @cofactors@, @adjugate@, @minor@, and+ @minorMatrix@. License: MIT License-File: LICENSE
src/Numeric/Matrix.hs view
@@ -38,61 +38,17 @@ Matrix, MatrixElement (..),- - -- * Matrix property and utility functions. - -- | Joins two matrices horizontally.- --- -- > 1 2 3 1 0 0 1 2 3 1 0 0- -- > 3 4 5 <|> 2 1 0 -> 3 4 5 2 1 0- -- > 5 6 7 3 2 1 5 6 7 3 2 1+ -- * Matrix property and utility functions. (<|>),-- -- | Joins two matrices vertically.- --- -- > 1 2 3 1 0 0 1 2 3- -- > 3 4 5 <-> 2 1 0 -> 3 4 5- -- > 5 6 7 3 2 1 5 6 7- -- > 1 0 0- -- > 2 1 0- -- > 3 2 1 (<->),-- -- | Scales a matrix by the given factor.- -- - -- > scale s == map (*s) scale, - -- * Matrix properties-- -- | Check whether the matrix is an identity matrix.- --- -- > 1 0 0- -- > 0 1 0- -- > 0 0 1 (True)+ -- ** Matrix properties isUnit,-- -- | Check whether the matrix consists of all zeros.- --- -- > isZero == all (== 0) isZero,-- -- | Checks whether the matrix is a diagonal matrix.- --- -- > 4 0 0 0- -- > 0 7 0 0- -- > 0 0 3 0- -- > 0 0 0 9 (True) isDiagonal,-- -- | Checks whether the matrix is empty.- --- -- > isEmpty m = numCols == 0 || numRows == 0 isEmpty,-- -- | Checks whether the matrix is a square matrix.- --- -- > isSquare == uncurry (==) . dimensions isSquare ) where@@ -123,17 +79,23 @@ data family Matrix e -data instance Matrix Int = IntMatrix !Int !Int (Array Int (UArray Int Int))+data instance Matrix Int+ = IntMatrix !Int !Int (Array Int (UArray Int Int)) -data instance Matrix Float = FloatMatrix !Int !Int (Array Int (UArray Int Float))+data instance Matrix Float+ = FloatMatrix !Int !Int (Array Int (UArray Int Float)) -data instance Matrix Double = DoubleMatrix !Int !Int (Array Int (UArray Int Double))+data instance Matrix Double+ = DoubleMatrix !Int !Int (Array Int (UArray Int Double)) -data instance Matrix Integer = IntegerMatrix !Int !Int (Array Int (Array Int Integer))+data instance Matrix Integer+ = IntegerMatrix !Int !Int (Array Int (Array Int Integer)) -data instance Matrix (Ratio a) = RatioMatrix !Int !Int (Array Int (Array Int (Ratio a)))+data instance Matrix (Ratio a)+ = RatioMatrix !Int !Int (Array Int (Array Int (Ratio a))) -data instance Matrix (Complex a) = ComplexMatrix !Int !Int (Array Int (Array Int (Complex a)))+data instance Matrix (Complex a)+ = ComplexMatrix !Int !Int (Array Int (Array Int (Complex a))) instance Typeable a => Typeable (Matrix a) where typeOf x = mkTyConApp (mkTyCon3 "bed-and-breakfast"@@ -171,6 +133,11 @@ (<|>) :: MatrixElement e => Matrix e -> Matrix e -> Matrix e+-- ^ Joins two matrices horizontally.+--+-- > 1 2 3 1 0 0 1 2 3 1 0 0+-- > 3 4 5 <|> 2 1 0 -> 3 4 5 2 1 0+-- > 5 6 7 3 2 1 5 6 7 3 2 1 m1 <|> m2 = let m = numCols m1 n1 = numRows m1 n2 = numRows m2@@ -180,6 +147,14 @@ else (if i > n1 then 0 else m1 `at` (i,j)) (<->) :: MatrixElement e => Matrix e -> Matrix e -> Matrix e+-- ^ Joins two matrices vertically.+--+-- > 1 2 3 1 0 0 1 2 3+-- > 3 4 5 <-> 2 1 0 -> 3 4 5+-- > 5 6 7 3 2 1 5 6 7+-- > 1 0 0+-- > 2 1 0+-- > 3 2 1 m1 <-> m2 = let m = numRows m1 n1 = numCols m1 n2 = numCols m2@@ -189,17 +164,44 @@ else (if j > n1 then 0 else m1 `at` (i,j)) scale :: MatrixElement e => Matrix e -> e -> Matrix e+-- ^ Scales a matrix by the given factor.+-- +-- > scale s == map (*s) scale m s = map (*s) m isUnit, isDiagonal, isZero, isEmpty, isSquare :: MatrixElement e => Matrix e -> Bool +-- | Check whether the matrix consists of all zeros.+--+-- > isZero == all (== 0) isZero = all (== 0)++-- | Check whether the matrix is an identity matrix.+--+-- > 1 0 0+-- > 0 1 0+-- > 0 0 1 (True) isUnit m = isSquare m && allWithIndex (uncurry check) m where check = \i j e -> if i == j then e == 1 else e == 0++-- | Checks whether the matrix is empty.+--+-- > isEmpty m = numCols == 0 || numRows == 0 isEmpty m = numRows m == 0 || numCols m == 0++-- | Checks whether the matrix is a diagonal matrix.+--+-- > 4 0 0 0+-- > 0 7 0 0+-- > 0 0 3 0+-- > 0 0 0 9 (True) isDiagonal m = isSquare m && allWithIndex (uncurry check) m where check = \i j e -> if i /= j then e == 0 else True++-- | Checks whether the matrix is a square matrix.+--+-- > isSquare == uncurry (==) . dimensions isSquare m = let (a, b) = dimensions m in a == b @@ -272,6 +274,11 @@ rank :: Matrix e -> e trace :: Matrix e -> [e] + minor :: MatrixElement e => Matrix e -> (Int, Int) -> e+ cofactors :: MatrixElement e => Matrix e -> Matrix e+ adjugate :: MatrixElement e => Matrix e -> Matrix e+ minorMatrix :: MatrixElement e => Matrix e -> (Int, Int) -> Matrix e+ -- Applies a function on every component in the matrix. map :: MatrixElement f => (e -> f) -> Matrix e -> Matrix f @@ -307,11 +314,20 @@ dimensions m = case toList m of [] -> (0, 0) (x:xs) -> (length xs + 1, length x) --- adjugate = transpose . cofactors+ adjugate = transpose . cofactors transpose = fromList . L.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)@@ -344,9 +360,8 @@ row i (IntMatrix _ _ arr) = _row i arr col j (IntMatrix _ _ arr) = _col j arr toList (IntMatrix _ _ arr) = _toList arr- inv _ = Nothing det (IntMatrix m n arr) = if m /= n then 0 else runST (_det thawsUnboxed arr)- rank = undefined -- runST (_rank thawsBoxed arr)+ rank (IntMatrix _ _ arr) = runST (_rank thawsBoxed arr) instance MatrixElement Integer where matrix = _matrix IntegerMatrix@@ -357,9 +372,8 @@ row i (IntegerMatrix _ _ arr) = _row i arr col j (IntegerMatrix _ _ arr) = _col j arr toList (IntegerMatrix _ _ arr) = _toList arr- inv _ = Nothing det (IntegerMatrix m n arr) = if m /= n then 0 else runST (_det thawsBoxed arr)- rank = undefined -- runST (_rank thawsBoxed arr)+ rank (IntegerMatrix _ _ arr) = runST (_rank thawsBoxed arr) instance MatrixElement Float where matrix = _matrix FloatMatrix@@ -370,11 +384,11 @@ row i (FloatMatrix _ _ arr) = _row i arr col j (FloatMatrix _ _ arr) = _col j arr toList (FloatMatrix _ _ arr) = _toList arr+ det (FloatMatrix m n arr) = if m /= n then 0 else runST (_det thawsUnboxed arr)+ rank (FloatMatrix _ _ arr) = runST (_rank thawsBoxed arr) inv (FloatMatrix m n arr) = if m /= n then Nothing else let x = runST (_inv unboxedST arr) in maybe Nothing (Just . FloatMatrix m n) x- det (FloatMatrix m n arr) = if m /= n then 0 else runST (_det thawsUnboxed arr)- rank (FloatMatrix _ _ arr) = runST (_rank thawsBoxed arr) instance MatrixElement Double where matrix = _matrix DoubleMatrix@@ -415,7 +429,7 @@ row i (ComplexMatrix _ _ arr) = _row i arr col j (ComplexMatrix _ _ arr) = _col j arr toList (ComplexMatrix _ _ arr) = _toList arr- inv (ComplexMatrix _ _ _) = Nothing+-- inv (ComplexMatrix _ _ _) = Nothing --if m /= n then Nothing else -- Just $ ComplexMatrix m n $ runST (_inv boxedST arr) det (ComplexMatrix m n arr) = if m /= n then 0 else runST (_det thawsBoxed arr)@@ -567,7 +581,7 @@ else return Nothing -_rank :: (IArray a e, MArray (u s) e (ST s), Fractional e, Eq e)+_rank :: (IArray a e, MArray (u s) e (ST s), Num e, Division e, Eq e) => (Array Int (a Int e) -> ST s [(u s) Int e]) -> Array Int (a Int e) -> ST s e@@ -586,7 +600,7 @@ a_kj <- readArray a_k j a_ik <- readArray a_i k a_kk <- readArray a_k k- writeArray a_i j (a_ij - a_kj * (a_ik / a_kk))+ writeArray a_i j (a_ij - a_kj * (a_ik `divide` a_kk)) writeArray a_i k 0 read a k k