packages feed

numeric-quest 0.2.0.3 → 0.2.1

raw patch · 6 files changed

+677/−10 lines, 6 filesdep +QuickCheckdep +doctest-exitcode-stdiodep +doctest-libdep ~base

Dependencies added: QuickCheck, doctest-exitcode-stdio, doctest-lib, non-empty, numeric-quest, utility-ht

Dependency ranges changed: base

Files

EigensystemNum.hs view
@@ -10,19 +10,20 @@ matSqr x = mult x x  powerIter :: (Fractional a, Ord a) => [[a]] -> [([[a]],[[a]])]-powerIter x = tail (iterate+powerIter x =+  tail $ iterate     (\(_,z)->let s=normalize (matSqr z) in (s,(mult x s)))     ([],x)-  )  normalize :: (Fractional a, Ord a) => [[a]] -> [[a]]-normalize x = map (map (/(matnorm1 x))) x+normalize x = map (map (/ matnorm1 x)) x  getGrowth :: (Fractional a, Ord a) => ([[a]],[[a]]) -> a-getGrowth (x,y) = uncurry (/) (maximumBy+getGrowth (x,y) =+  uncurry (/) $+  maximumBy     (\(_,xc) (_,xa) -> compare (abs xc) (abs xa))     (concat (zipWith zip y x))-  )  specRadApprox :: (Fractional a, Ord a) => [[a]] -> [a] specRadApprox = map getGrowth . powerIter@@ -31,7 +32,8 @@ eigenValuesApprox = map diagonals . iterate similar_to  limit :: (Num a, Ord a) => a -> [a] -> a-limit tol (x0:x1:xs) = if abs (x1-x0) < tol * abs x0-                       then x0-		       else limit tol (x1:xs)+limit tol (x0:x1:xs) =+    if abs (x1-x0) < tol * abs x0+    then x0+    else limit tol (x1:xs) limit _ _ = error "Only infinite sequences are allowed"
Makefile view
@@ -3,3 +3,14 @@  %.html:	%.lhs 	ln -s $< $@++++run-test:	update-test+	runhaskell Setup.lhs configure --user --enable-tests+	runhaskell Setup.lhs build+	runhaskell Setup.lhs haddock+	./dist/build/numeric-quest-test/numeric-quest-test++update-test:+	doctest-extract-0.1 -o test/ --executable-main=Test/Main.hs RowEchelon
+ RowEchelon.hs view
@@ -0,0 +1,412 @@+{- |+<https://en.wikipedia.org/wiki/Row_echelon_form>++Duplicate of @htam@ package.+-}+module RowEchelon (+   Matrix(Matrix), matrixRows, matrixWidth, matrixHeight,+   shortBesidesTall, (|||),+   matrixValid, matrixFromRows,+   identity, matrixProduct,+   nullspace, reducedRowEchelon, rowReduction, layoutEchelonBlocks,+   scatter,+   Zipper0(Zipper0), Zipper1(Zipper1), altOuter,+   ) where++import Orthogonals (matrix_matrix)++import qualified Data.Foldable as Fold+import qualified Data.NonEmpty as NonEmpty+import qualified Data.List.HT as ListHT+import qualified Data.List as List+import Data.NonEmpty ((!:))+import Data.Maybe (fromMaybe)+++{- $setup+>>> import RowEchelon as Matrix+>>> import qualified Test.QuickCheck as QC+>>> import Test.QuickCheck ((===))+>>> import Control.Monad (replicateM)+>>> import qualified Data.Foldable as Fold+>>> import qualified Data.NonEmpty.Class as NonEmptyC+>>> import qualified Data.NonEmpty as NonEmpty+>>> import qualified Data.List.Match as Match+>>> import qualified Data.List.HT as ListHT+>>> import Data.NonEmpty ((!:))+>>> import Data.Ratio ((%))+>>>+>>> genElementUniform, genElementNearZero :: QC.Gen Integer+>>> genElementUniform = QC.choose (-10,10)+>>> genElementNearZero = fmap (flip rem 11) $ QC.arbitrary+>>>+>>> genMatrixForSize :: Int -> Int -> QC.Gen (Matrix Integer)+>>> genMatrixForSize m n = do+>>>    fmap (Matrix n) $ replicateM m $ replicateM n genElementNearZero+>>>+>>> genMatrix :: QC.Gen (Matrix Integer)+>>> genMatrix = do+>>>    m <- QC.choose (0,10)+>>>    n <- QC.choose (0,10)+>>>    genMatrixForSize m n+>>>+>>> shrinkMatrix :: (Eq a) => Matrix a -> [Matrix a]+>>> shrinkMatrix matrix@(Matrix width rows) =+>>>    filter (matrix/=) $+>>>    map (Matrix width . snd) (ListHT.removeEach rows)+>>>    +++>>>    [Matrix (width-1) $ map (drop 1) rows]+>>>+>>> forMatrix :: (QC.Testable test) => (Matrix Rational -> test) -> QC.Property+>>> forMatrix prop =+>>>    QC.forAllShrink genMatrix shrinkMatrix (prop . rationalMatrix)+>>>+>>> rationalMatrix :: Matrix Integer -> Matrix Rational+>>> rationalMatrix = fmap (%1)+-}+++data Zipper0 a = Zipper0 [a] [a]+   deriving (Eq, Show)++data Zipper1 a = Zipper1 [a] a [a]+   deriving (Eq, Show)++instance Functor Zipper0 where+   fmap f (Zipper0 xs ys) = Zipper0 (fmap f xs) (fmap f ys)++instance Functor Zipper1 where+   fmap f (Zipper1 xs y zs) = Zipper1 (fmap f xs) (f y) (fmap f zs)++zipper0FromList :: [a] -> Zipper0 a+zipper0FromList = Zipper0 []+++type List0 = []+type List1 = NonEmpty.T List0++-- data Matrix a = Matrix {matrixWidth :: Int, matrixRows :: [[a]]}+data Matrix a = Matrix Int [[a]]+   deriving (Eq, Show)++instance Functor Matrix where+   fmap f (Matrix width rows) = Matrix width $ map (map f) rows++instance Foldable Matrix where+   foldMap f (Matrix _width rows) = foldMap (foldMap f) rows++matrixValid :: Matrix a -> Bool+matrixValid (Matrix width rows) = all ((width==) . length) rows++matrixWidth :: Matrix a -> Int+matrixWidth (Matrix width _) = width++matrixHeight :: Matrix a -> Int+matrixHeight = length . matrixRows++matrixRows :: Matrix a -> [[a]]+matrixRows (Matrix _ rows) = rows++matrixFromRows :: [[a]] -> Matrix a+matrixFromRows rows =+   Matrix (ListHT.switchL 0 (const . length) rows) rows++infixr 3 |||++-- | requires that both matrices have the same height+(|||) :: Matrix a -> Matrix a -> Matrix a+Matrix widthA a ||| Matrix widthB b =+   Matrix (widthA+widthB) (zipWith (++) a b)++{- |+The expression @shortBesidesTall a b@ means:++> /A  B_upper\+> |          |+> \0  B_lower/++Matrix @a@ must be at most as tall as @b@.+-}+shortBesidesTall :: (Num a) => Matrix a -> Matrix a -> Matrix a+shortBesidesTall a b =+   Matrix (matrixWidth a + matrixWidth b) $+   zipWith (++)+      (matrixRows a ++ repeat (replicate (matrixWidth a) 0))+      (matrixRows b)++matrixProduct :: (Num a) => Matrix a -> Matrix a -> Matrix a+matrixProduct (Matrix _ x) (Matrix width y) =+   Matrix width $ matrix_matrix x $ List.transpose y++{- |+>>> nullspace (Matrix 2 []) :: Matrix Rational+Matrix 2 [[1 % 1,0 % 1],[0 % 1,1 % 1]]+++prop> forMatrix $ matrixValid . nullspace+++prop> :{+   forMatrix $ \matrix ->+      matrixWidth matrix == matrixHeight (nullspace matrix)+:}++prop> :{+   forMatrix $ \matrix ->+      matrixWidth (nullspace matrix) <= matrixWidth matrix+:}++max 0 (width matrix - height matrix) <= width nullspace++prop> :{+   forMatrix $ \matrix ->+      matrixWidth matrix <= matrixWidth (nullspace matrix) + matrixHeight matrix+:}++prop> :{+   forMatrix $ \matrix ->+      Fold.all (0==) $ matrixProduct matrix (nullspace matrix)+:}+-}+nullspace :: (RealFrac a) => Matrix a -> Matrix a+nullspace matrix =+   let echelon = reducedRowEchelon matrix in+   let flat = layoutEchelonBlocks echelon in+   let nullDim = matrixWidth flat in+   Matrix nullDim $+   scatter+      (fmap matrixWidth $ altOuter echelon)+      (matrixRows $ fmap negate flat) $+   matrixRows $ identity nullDim++identity :: (Num a) => Int -> Matrix a+identity n = Matrix n $ take n $ map (take n) $ iterate (0:) $ 1 : repeat 0+++-- cf. event-list+data AlternatingList a b = AlternatingList a [(b,a)]+   deriving (Eq)++instance (Show a, Show b) => Show (AlternatingList a b) where+   showsPrec p xs =+      showParen (p>=5) $+      flip+         (altFoldr+            (\a -> showsPrec 5 a . showString " ./ ")+            (\b -> showsPrec 5 b . showString " /. "))+         xs+      .+      showString "[]"++altSingleton :: a -> AlternatingList a b+altSingleton a = AlternatingList a []++infixr 5 /. , ./++(./) = altConsOuter+(/.) = altConsInner++altConsOuter, (./) :: a -> List0 (b,a) -> AlternatingList a b+altConsOuter = AlternatingList++altConsInner, (/.) :: b -> AlternatingList a b -> List0 (b,a)+altConsInner b ~(AlternatingList a bas) = (b,a) : bas++altOuter :: AlternatingList a b -> List1 a+altOuter (AlternatingList a bas) = a !: map snd bas++altFoldr :: (a -> c -> d) -> (b -> d -> c) -> c -> AlternatingList a b -> d+altFoldr f g c (AlternatingList a0 bas) =+   f a0 $ foldr (\(b,a) -> g b . f a) c bas+++{- |+>>> scatter (3 !: 1 : 4 : 1 : []) "012" ['a'..'k']+"abc0d1efgh2ijk"+-}+scatter :: List1 Int -> [a] -> [a] -> [a]+scatter (NonEmpty.Cons k_ ks_) =+   let go _k [] [] dst = dst+       go k0 (k1:ks) (a:as) dst =+         case splitAt k0 dst of+            (prefix,suffix) -> prefix ++ a : go k1 ks as suffix+       go _ _ _ _ = error "scatter: inconsistent lengths"+   in go k_ ks_+++{- |+> mapM_ print $ layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[1,3,0,5],[0,0,1,7::Rational]]++>>> layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[0::Rational]]+Matrix 1 []++>>> layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[1,3,0,5::Rational]]+Matrix 3 [[3 % 1,0 % 1,5 % 1]]++>>> layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[0,1,3,5::Rational]]+Matrix 3 [[0 % 1,3 % 1,5 % 1]]++>>> layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[1,3,0,5],[0,0,1,7::Rational]]+Matrix 2 [[3 % 1,5 % 1],[0 % 1,7 % 1]]++prop> :{+   forMatrix $ \matrix ->+      (layoutEchelonBlocks $ reducedRowEchelon $+         identity (matrixHeight matrix) ||| matrix)+      ===+      matrix+:}++Construct a matrix that is already in Echelon form+and check that it is preserved by Echelon decomposition.++prop> :{+   QC.forAll (fmap (flip mod 10) . NonEmpty.mapTail (take 9) <$> QC.arbitrary) $+      \blockWidths ->+   QC.forAll (traverse (uncurry genMatrixForSize) $+               NonEmptyC.zip (0!:[1..]) blockWidths) $+      \blocksInt ->++      let blocks :: NonEmpty.T [] (Matrix Rational)+          blocks = fmap (fmap (%1)) blocksInt+          unitBesidesBlock block =+            Matrix (matrixWidth block + 1) $+            zipWith (:)+               (drop 1 $ Match.replicate (matrixRows block) 0 ++ [1])+               (matrixRows block)+          echelonWithInterleavedEye =+            Fold.foldr1 shortBesidesTall $+            NonEmpty.mapTail (map unitBesidesBlock) blocks+      in++      layoutEchelonBlocks (reducedRowEchelon echelonWithInterleavedEye)+      ===+      Fold.foldr1 shortBesidesTall blocks+:}+-}+layoutEchelonBlocks :: (Num a) => AlternatingList (Matrix a) a -> Matrix a+layoutEchelonBlocks = Fold.foldr1 shortBesidesTall . altOuter+++{-+/I B\           /0\+|   | * P * x = | |+\0 0/           \0/++B is a rectangular upper block triangular matrix with non-uniform block size.++The solution is++      /-B\+P*X = |  |+      \ I/++such that++        /-B\+(I B) * |  | = I*(-B) + B*I = 0+        \ I/++This is the nullspace:++      /-B\+P^T * |  |+      \ I/++The null-space vectors have the form+/* * *\+|1 0 0|+|* * *|+|* * *|+|* * *|+|0 1 0|+|* * *|+|0 0 1|+|* * *|+\* * */+-}+{- |+>>> reducedRowEchelon $ matrixFromRows [[2,1,3::Rational]]+Matrix 0 [] ./ 2 % 1 /. Matrix 2 [[1 % 2,3 % 2]] ./ []++>>> reducedRowEchelon $ matrixFromRows [[2],[1],[3::Rational]]+Matrix 0 [] ./ 3 % 1 /. Matrix 0 [[]] ./ []++>>> reducedRowEchelon $ matrixFromRows [[1,0,2],[0,1,3::Rational]]+Matrix 0 [] ./ 1 % 1 /. Matrix 0 [[]] ./ 1 % 1 /. Matrix 1 [[2 % 1],[3 % 1]] ./ []++>>> reducedRowEchelon $ matrixFromRows [[1,3,0,5],[0,0,1,7::Rational]]+Matrix 0 [] ./ 1 % 1 /. Matrix 1 [[3 % 1]] ./ 1 % 1 /. Matrix 1 [[5 % 1],[7 % 1]] ./ []++prop> :{+   forMatrix $ \matrix ->+      Fold.all matrixValid $ altOuter $ reducedRowEchelon matrix+:}+-}+reducedRowEchelon :: (RealFrac a) => Matrix a -> AlternatingList (Matrix a) a+reducedRowEchelon matrix@(Matrix _ []) = altSingleton matrix+reducedRowEchelon (Matrix _ rows) =+   let go matrix@(Zipper0 upper _lower) =+         case rowReduction matrix of+            (n, Nothing) -> altSingleton (Matrix n $ reverse upper)+            (n, Just (hd, block, remaining)) ->+               Matrix n block ./ hd /. go remaining+   in go $ zipper0FromList rows++{- |+>>> rowReduction $ Zipper0 [[1,2,3,4,5],[6,7,8,9,10::Rational]] [[0,2,0,0,0],[3,0,0,0,0]]+(0,Just (3 % 1,[[],[]],Zipper0 [[0 % 1,0 % 1,0 % 1,0 % 1],[2 % 1,3 % 1,4 % 1,5 % 1],[7 % 1,8 % 1,9 % 1,10 % 1]] [[2 % 1,0 % 1,0 % 1,0 % 1]]))+-}+rowReduction ::+   (RealFrac a) => Zipper0 [a] -> (Int, Maybe (a, [[a]], Zipper0 [a]))+rowReduction (Zipper0 upper []) =+   (ListHT.switchL 0 (\row _rows -> length row) upper, Nothing)+rowReduction (Zipper0 upper (focus:lower)) =+   case shiftUntilNonZeroColumn 0 $ Zipper1 upper focus lower of+      (n, Nothing) -> (n, Nothing)+      (n, Just (Zipper1 upperNE (NonEmpty.Cons maxRowHead maxRow) lowerNE)) ->+         (n, Just $+            let maxRowNormalized = map (/maxRowHead) maxRow in+            (maxRowHead,+             map (take n) $ reverse upper,+             Zipper0+               (maxRowNormalized :+                map (cancelRow maxRowNormalized) upperNE)+               (map (cancelRow maxRowNormalized) lowerNE)))++cancelRow :: (Num a) => List0 a -> List1 a -> List0 a+cancelRow xs (NonEmpty.Cons y0 ys) = zipWith (-) ys $ map (y0*) xs+++shiftUntilNonZeroColumn ::+   (Real a) => Int -> Zipper1 [a] -> (Int, Maybe (Zipper1 (List1 a)))+shiftUntilNonZeroColumn n matrix =+   case checkHeads matrix of+      Nothing -> (n, Nothing)+      Just matrixNE@(Zipper1 upperNE foucsNE lowerNE) ->+         case maxHead (foucsNE!:lowerNE) of+            (maxRow, lowerWithoutMax) ->+               if NonEmpty.head maxRow == 0+               then (shiftUntilNonZeroColumn $! (n+1)) $+                    fmap NonEmpty.tail matrixNE+               else (n, Just (Zipper1 upperNE maxRow lowerWithoutMax))++maxHead :: (Real a) => List1 (List1 a) -> (List1 a, [List1 a])+maxHead = NonEmpty.maximumKey (abs . NonEmpty.head . fst) . NonEmpty.removeEach++checkHeads :: Zipper1 [a] -> Maybe (Zipper1 (List1 a))+checkHeads (Zipper1 upper focus lower) =+   case NonEmpty.fetch focus of+      Nothing ->+         if all null (upper++lower) then Nothing else error "row lengths differ"+      Just xs -> Just $+         Zipper1+            (fromMaybe (error "upper row lengths differ") $ allNonEmpty upper)+            xs+            (fromMaybe (error "lower row lengths differ") $ allNonEmpty lower)++allNonEmpty :: [List0 a] -> Maybe [List1 a]+allNonEmpty xs =+   case ListHT.partitionMaybe NonEmpty.fetch xs of+      (ne,[]) -> Just ne+      _ -> Nothing
numeric-quest.cabal view
@@ -1,5 +1,5 @@ Name:           numeric-quest-Version:        0.2.0.3+Version:        0.2.1 License:        GPL License-File:   LICENSE Author:         Jan Skibinski@@ -25,7 +25,7 @@   README  Source-Repository this-  Tag:         0.2.0.3+  Tag:         0.2.1   Type:        darcs   Location:    http://code.haskell.org/~thielema/numeric-quest/ @@ -35,6 +35,8 @@  Library   Build-Depends:+    non-empty >=0.3.2 && <0.4,+    utility-ht >=0.0.2 && <0.1,     prelude-compat >=0.0.0.1 && <0.1,     array >=0.1 && <0.6,     base >=3 && <5@@ -50,4 +52,22 @@      Orthogonals      QuantumVector      Roots+     RowEchelon      Tensor++Test-Suite numeric-quest-test+  Type: exitcode-stdio-1.0+  Default-Language: Haskell98+  GHC-Options:    -Wall+  Hs-Source-Dirs: test+  Other-Modules:  Test.RowEchelon+  Main-Is: Test/Main.hs++  Build-Depends:+    numeric-quest,+    doctest-exitcode-stdio >=0.0 && <0.1,+    doctest-lib >=0.1 && <0.2,+    QuickCheck >=2 && <3,+    non-empty,+    utility-ht,+    base
+ test/Test/Main.hs view
@@ -0,0 +1,10 @@+-- Do not edit! Automatically created with doctest-extract.+module Main where++import qualified Test.RowEchelon++import qualified Test.DocTest.Driver as DocTest++main :: IO ()+main = DocTest.run $ do+    Test.RowEchelon.test
+ test/Test/RowEchelon.hs view
@@ -0,0 +1,212 @@+-- Do not edit! Automatically created with doctest-extract from RowEchelon.hs+{-# LINE 26 "RowEchelon.hs" #-}++module Test.RowEchelon where++import Test.DocTest.Base+import qualified Test.DocTest.Driver as DocTest++{-# LINE 27 "RowEchelon.hs" #-}+import     RowEchelon as Matrix+import     qualified Test.QuickCheck as QC+import     Test.QuickCheck ((===))+import     Control.Monad (replicateM)+import     qualified Data.Foldable as Fold+import     qualified Data.NonEmpty.Class as NonEmptyC+import     qualified Data.NonEmpty as NonEmpty+import     qualified Data.List.Match as Match+import     qualified Data.List.HT as ListHT+import     Data.NonEmpty ((!:))+import     Data.Ratio ((%))++genElementUniform,     genElementNearZero :: QC.Gen Integer+genElementUniform     = QC.choose (-10,10)+genElementNearZero     = fmap (flip rem 11) $ QC.arbitrary++genMatrixForSize     :: Int -> Int -> QC.Gen (Matrix Integer)+genMatrixForSize     m n = do+       fmap (Matrix n) $ replicateM m $ replicateM n genElementNearZero++genMatrix     :: QC.Gen (Matrix Integer)+genMatrix     = do+       m <- QC.choose (0,10)+       n <- QC.choose (0,10)+       genMatrixForSize m n++shrinkMatrix     :: (Eq a) => Matrix a -> [Matrix a]+shrinkMatrix     matrix@(Matrix width rows) =+       filter (matrix/=) $+       map (Matrix width . snd) (ListHT.removeEach rows)+       +++       [Matrix (width-1) $ map (drop 1) rows]++forMatrix     :: (QC.Testable test) => (Matrix Rational -> test) -> QC.Property+forMatrix     prop =+       QC.forAllShrink genMatrix shrinkMatrix (prop . rationalMatrix)++rationalMatrix     :: Matrix Integer -> Matrix Rational+rationalMatrix     = fmap (%1)++test :: DocTest.T ()+test = do+ DocTest.printPrefix "RowEchelon:142: "+{-# LINE 142 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 142 "RowEchelon.hs" #-}+    nullspace (Matrix 2 []) :: Matrix Rational+  )+  [ExpectedLine [LineChunk "Matrix 2 [[1 % 1,0 % 1],[0 % 1,1 % 1]]"]]+ DocTest.printPrefix "RowEchelon:146: "+{-# LINE 146 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 146 "RowEchelon.hs" #-}+      forMatrix $ matrixValid . nullspace+  )+ DocTest.printPrefix "RowEchelon:149: "+{-# LINE 149 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 149 "RowEchelon.hs" #-}+        +   forMatrix $ \matrix ->+      matrixWidth matrix == matrixHeight (nullspace matrix)+  )+ DocTest.printPrefix "RowEchelon:154: "+{-# LINE 154 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 154 "RowEchelon.hs" #-}+        +   forMatrix $ \matrix ->+      matrixWidth (nullspace matrix) <= matrixWidth matrix+  )+ DocTest.printPrefix "RowEchelon:161: "+{-# LINE 161 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 161 "RowEchelon.hs" #-}+        +   forMatrix $ \matrix ->+      matrixWidth matrix <= matrixWidth (nullspace matrix) + matrixHeight matrix+  )+ DocTest.printPrefix "RowEchelon:166: "+{-# LINE 166 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 166 "RowEchelon.hs" #-}+        +   forMatrix $ \matrix ->+      Fold.all (0==) $ matrixProduct matrix (nullspace matrix)+  )+ DocTest.printPrefix "RowEchelon:224: "+{-# LINE 224 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 224 "RowEchelon.hs" #-}+    scatter (3 !: 1 : 4 : 1 : []) "012" ['a'..'k']+  )+  [ExpectedLine [LineChunk "\"abc0d1efgh2ijk\""]]+ DocTest.printPrefix "RowEchelon:240: "+{-# LINE 240 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 240 "RowEchelon.hs" #-}+    layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[0::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 1 []"]]+ DocTest.printPrefix "RowEchelon:243: "+{-# LINE 243 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 243 "RowEchelon.hs" #-}+    layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[1,3,0,5::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 3 [[3 % 1,0 % 1,5 % 1]]"]]+ DocTest.printPrefix "RowEchelon:246: "+{-# LINE 246 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 246 "RowEchelon.hs" #-}+    layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[0,1,3,5::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 3 [[0 % 1,3 % 1,5 % 1]]"]]+ DocTest.printPrefix "RowEchelon:249: "+{-# LINE 249 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 249 "RowEchelon.hs" #-}+    layoutEchelonBlocks $ reducedRowEchelon $ matrixFromRows [[1,3,0,5],[0,0,1,7::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 2 [[3 % 1,5 % 1],[0 % 1,7 % 1]]"]]+ DocTest.printPrefix "RowEchelon:252: "+{-# LINE 252 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 252 "RowEchelon.hs" #-}+        +   forMatrix $ \matrix ->+      (layoutEchelonBlocks $ reducedRowEchelon $+         identity (matrixHeight matrix) ||| matrix)+      ===+      matrix+  )+ DocTest.printPrefix "RowEchelon:263: "+{-# LINE 263 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 263 "RowEchelon.hs" #-}+        +   QC.forAll (fmap (flip mod 10) . NonEmpty.mapTail (take 9) <$> QC.arbitrary) $+      \blockWidths ->+   QC.forAll (traverse (uncurry genMatrixForSize) $+               NonEmptyC.zip (0!:[1..]) blockWidths) $+      \blocksInt ->++      let blocks :: NonEmpty.T [] (Matrix Rational)+          blocks = fmap (fmap (%1)) blocksInt+          unitBesidesBlock block =+            Matrix (matrixWidth block + 1) $+            zipWith (:)+               (drop 1 $ Match.replicate (matrixRows block) 0 ++ [1])+               (matrixRows block)+          echelonWithInterleavedEye =+            Fold.foldr1 shortBesidesTall $+            NonEmpty.mapTail (map unitBesidesBlock) blocks+      in++      layoutEchelonBlocks (reducedRowEchelon echelonWithInterleavedEye)+      ===+      Fold.foldr1 shortBesidesTall blocks+  )+ DocTest.printPrefix "RowEchelon:329: "+{-# LINE 329 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 329 "RowEchelon.hs" #-}+    reducedRowEchelon $ matrixFromRows [[2,1,3::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 0 [] ./ 2 % 1 /. Matrix 2 [[1 % 2,3 % 2]] ./ []"]]+ DocTest.printPrefix "RowEchelon:332: "+{-# LINE 332 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 332 "RowEchelon.hs" #-}+    reducedRowEchelon $ matrixFromRows [[2],[1],[3::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 0 [] ./ 3 % 1 /. Matrix 0 [[]] ./ []"]]+ DocTest.printPrefix "RowEchelon:335: "+{-# LINE 335 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 335 "RowEchelon.hs" #-}+    reducedRowEchelon $ matrixFromRows [[1,0,2],[0,1,3::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 0 [] ./ 1 % 1 /. Matrix 0 [[]] ./ 1 % 1 /. Matrix 1 [[2 % 1],[3 % 1]] ./ []"]]+ DocTest.printPrefix "RowEchelon:338: "+{-# LINE 338 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 338 "RowEchelon.hs" #-}+    reducedRowEchelon $ matrixFromRows [[1,3,0,5],[0,0,1,7::Rational]]+  )+  [ExpectedLine [LineChunk "Matrix 0 [] ./ 1 % 1 /. Matrix 1 [[3 % 1]] ./ 1 % 1 /. Matrix 1 [[5 % 1],[7 % 1]] ./ []"]]+ DocTest.printPrefix "RowEchelon:341: "+{-# LINE 341 "RowEchelon.hs" #-}+ DocTest.property(+{-# LINE 341 "RowEchelon.hs" #-}+        +   forMatrix $ \matrix ->+      Fold.all matrixValid $ altOuter $ reducedRowEchelon matrix+  )+ DocTest.printPrefix "RowEchelon:357: "+{-# LINE 357 "RowEchelon.hs" #-}+ DocTest.example(+{-# LINE 357 "RowEchelon.hs" #-}+    rowReduction $ Zipper0 [[1,2,3,4,5],[6,7,8,9,10::Rational]] [[0,2,0,0,0],[3,0,0,0,0]]+  )+  [ExpectedLine [LineChunk "(0,Just (3 % 1,[[],[]],Zipper0 [[0 % 1,0 % 1,0 % 1,0 % 1],[2 % 1,3 % 1,4 % 1,5 % 1],[7 % 1,8 % 1,9 % 1,10 % 1]] [[2 % 1,0 % 1,0 % 1,0 % 1]]))"]]