diff --git a/Math/ExpPairs/Ivic.hs b/Math/ExpPairs/Ivic.hs
--- a/Math/ExpPairs/Ivic.hs
+++ b/Math/ExpPairs/Ivic.hs
@@ -61,7 +61,7 @@
 -- and that alpha2 <= 1 for S >= 2/3 or S >= 5/8 and
 --          (4S-2)k + (8S-6)l + 2S-1 >=0
 
--- | Compute m(σ) such that ∫_1^T |ζ(σ+it)|^m(σ) dt ≪ T^(1+ε)
+-- | Compute m(σ) such that ∫_1^T |ζ(σ+it)|^m(σ) dt ≪ T^(1+ε).
 -- See equation (8.97) in Ivić2003.
 mOnS :: Rational -> OptimizeResult
 mOnS s
diff --git a/Math/ExpPairs/Matrix3.hs b/Math/ExpPairs/Matrix3.hs
--- a/Math/ExpPairs/Matrix3.hs
+++ b/Math/ExpPairs/Matrix3.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE BangPatterns, RecordWildCards, DeriveFunctor, DeriveFoldable, DeriveGeneric #-}
 {-|
 Module      : Math.ExpPairs.Matrix3
 Description : Implements matrices of order 3
@@ -10,39 +11,62 @@
 Provides types and functions for matrices and vectors of order 3.
 Can be used instead of "Data.Matrix" to reduce overhead and simplify code.
 -}
-module Math.ExpPairs.Matrix3 (Matrix3 (..), Vector3 (..), fromList, toList, det, multCol, normalize, prettyMatrix) where
+module Math.ExpPairs.Matrix3
+	( Matrix3 (..)
+	, Vector3 (..)
+	, fromList
+	, toList
+	, det
+	, multCol
+	, normalize
+	, prettyMatrix
+	) where
 
-import qualified Data.List as List
-import Data.Monoid
+import Prelude hiding (foldl1)
+import Data.Foldable (Foldable (..), toList)
+import GHC.Generics (Generic (..))
 
 -- |Three-component vector.
 data Vector3 t = Vector3 {
-	a1 :: t,
-	a2 :: t,
-	a3 :: t
+	a1 :: !t,
+	a2 :: !t,
+	a3 :: !t
 	}
-	deriving (Eq, Show)
+	deriving (Eq, Show, Functor, Foldable, Generic)
 
--- |Matrix of order 3. Instances of 'Num', 'Fractional' and 'Monoid'
--- are defined in terms of the multiplicative group of matrices,
+-- |Matrix of order 3. Instances of 'Num' and 'Fractional'
+-- are given in terms of the multiplicative group of matrices,
 -- not the additive one. E. g.,
 --
 -- > toList 1 == [1,0,0,0,1,0,0,0,1]
 -- > toList 1 /= [1,1,1,1,1,1,1,1,1]
 --
 data Matrix3 t = Matrix3 {
-	a11 :: t,
-	a12 :: t,
-	a13 :: t,
-	a21 :: t,
-	a22 :: t,
-	a23 :: t,
-	a31 :: t,
-	a32 :: t,
-	a33 :: t
+	a11 :: !t,
+	a12 :: !t,
+	a13 :: !t,
+	a21 :: !t,
+	a22 :: !t,
+	a23 :: !t,
+	a31 :: !t,
+	a32 :: !t,
+	a33 :: !t
 	}
-	deriving (Eq, Show)
+	deriving (Eq, Show, Functor, Foldable, Generic)
 
+diag :: Num t => t -> Matrix3 t
+diag n = Matrix3 {
+	a11 = n,
+	a12 = 0,
+	a13 = 0,
+	a21 = 0,
+	a22 = n,
+	a23 = 0,
+	a31 = 0,
+	a32 = 0,
+	a33 = n
+	}
+
 instance Num t => Num (Matrix3 t) where
 	a + b = Matrix3 {
 		a11 = a11 a + a11 b,
@@ -69,128 +93,77 @@
 		a33 = a31 a * a13 b + a32 a * a23 b + a33 a * a33 b
 		}
 
-	negate a = Matrix3 {
-		a11 = - a11 a,
-		a12 = - a12 a,
-		a13 = - a13 a,
-		a21 = - a21 a,
-		a22 = - a22 a,
-		a23 = - a23 a,
-		a31 = - a31 a,
-		a32 = - a32 a,
-		a33 = - a33 a
-		}
+	negate = fmap negate
 
 	abs = undefined
 
-	signum = undefined
+	signum = diag . signum . det
 
-	-- Multiplicative, not additive behaviour
-	fromInteger n = Matrix3 {
-		a11 = fromInteger n,
-		a12 = 0,
-		a13 = 0,
-		a21 = 0,
-		a22 = fromInteger n,
-		a23 = 0,
-		a31 = 0,
-		a32 = 0,
-		a33 = fromInteger n
-		}
+	fromInteger = diag . fromInteger
 
 -- |Computes the determinant of a matrix.
-det :: (Num t) => Matrix3 t -> t
-det a =
-	a11 a * (a22 a * a33 a - a32 a * a23 a)
-	- a12 a * (a21 a * a33 a - a23 a * a31 a)
-	+ a13 a * (a21 a * a32 a - a22 a * a31 a)
+det :: Num t => Matrix3 t -> t
+det Matrix3 {..} =
+	a11 * (a22 * a33 - a32 * a23)
+	- a12 * (a21 * a33 - a23 * a31)
+	+ a13 * (a21 * a32 - a22 * a31)
 
 instance Fractional t => Fractional (Matrix3 t) where
-	-- Multiplicative, not additive behaviour
-	fromRational n = Matrix3 {
-		a11 = fromRational n,
-		a12 = 0,
-		a13 = 0,
-		a21 = 0,
-		a22 = fromRational n,
-		a23 = 0,
-		a31 = 0,
-		a32 = 0,
-		a33 = fromRational n
-		}
+	fromRational = diag . fromRational
 
-	recip a = Matrix3 {
-		a11 =  (a22 a * a33 a - a32 a * a23 a) / d,
-		a12 = -(a21 a * a33 a - a23 a * a31 a) / d,
-		a13 =  (a21 a * a32 a - a22 a * a31 a) / d,
-		a21 = -(a12 a * a33 a - a13 a * a32 a) / d,
-		a22 =  (a11 a * a33 a - a13 a * a31 a) / d,
-		a23 = -(a11 a * a32 a - a12 a * a31 a) / d,
-		a31 =  (a12 a * a23 a - a13 a * a22 a) / d,
-		a32 = -(a11 a * a23 a - a13 a * a21 a) / d,
-		a33 =  (a11 a * a22 a - a12 a * a21 a) / d
+	recip a@(Matrix3 {..}) = Matrix3 {
+		a11 =  (a22 * a33 - a32 * a23) / d,
+		a12 = -(a21 * a33 - a23 * a31) / d,
+		a13 =  (a21 * a32 - a22 * a31) / d,
+		a21 = -(a12 * a33 - a13 * a32) / d,
+		a22 =  (a11 * a33 - a13 * a31) / d,
+		a23 = -(a11 * a32 - a12 * a31) / d,
+		a31 =  (a12 * a23 - a13 * a22) / d,
+		a32 = -(a11 * a23 - a13 * a21) / d,
+		a33 =  (a11 * a22 - a12 * a21) / d
 		} where d = det a
 
-
-instance Num t => Monoid (Matrix3 t) where
-	mempty = 1
-	mappend = (*)
-
--- |Convert 'Matrix3' into a list of 9 elements.
-toList :: Matrix3 t -> [t]
-toList a = [a11 a, a12 a, a13 a, a21 a, a22 a, a23 a, a31 a, a32 a, a33 a]
-
--- |Convert a list of 9 elements into 'Matrix3'.
+-- |Convert a list of 9 elements into 'Matrix3'. Reverse conversion can be done using 'Foldable' instance.
 fromList :: [t] -> Matrix3 t
-fromList as = Matrix3 {
-		a11 = as!!0,
-		a12 = as!!1,
-		a13 = as!!2,
-		a21 = as!!3,
-		a22 = as!!4,
-		a23 = as!!5,
-		a31 = as!!6,
-		a32 = as!!7,
-		a33 = as!!8
-		}
-
-instance Functor Matrix3 where
-	fmap f = fromList . List.map f . toList
+fromList [a11, a12, a13, a21, a22, a23, a31, a32, a33] = Matrix3 {
+	a11 = a11,
+	a12 = a12,
+	a13 = a13,
+	a21 = a21,
+	a22 = a22,
+	a23 = a23,
+	a31 = a31,
+	a32 = a32,
+	a33 = a33
+	}
+fromList _ = error "The list must contain exactly 9 elements"
 
 -- |Divide all elements of the matrix by their greatest common
 -- divisor. This is useful for matrices of projective
 -- transformations to reduce the magnitude of computations.
 normalize :: Integral t => Matrix3 t -> Matrix3 t
-normalize m = m' where
-	l = toList m
-	d = foldl1 gcd l
-	m' = if d==0 then m else fromList $ List.map (`div`d) l
-
--- |Return the maximal element of a matrix.
-maximum :: Ord t => Matrix3 t -> t
-maximum = List.maximum . toList
+normalize a = case foldl1 gcd a of
+	0 -> a
+	d -> fmap (`div` d) a
 
 -- |Print a matrix, separating rows with new lines and elements
 -- with spaces.
-prettyMatrix :: (Show t) => Matrix3 t -> String
-prettyMatrix m =
-	show (a11 m) ++ " " ++
-	show (a12 m) ++ " " ++
-	show (a13 m) ++ "\n" ++
-	show (a21 m) ++ " " ++
-	show (a22 m) ++ " " ++
-	show (a23 m) ++ "\n" ++
-	show (a31 m) ++ " " ++
-	show (a32 m) ++ " " ++
-	show (a33 m)
+prettyMatrix :: Show t => Matrix3 t -> String
+prettyMatrix Matrix3 {..} =
+	show a11 ++ ' '  :
+	show a12 ++ ' '  :
+	show a13 ++ '\n' :
+	show a21 ++ ' '  :
+	show a22 ++ ' '  :
+	show a23 ++ '\n' :
+	show a31 ++ ' '  :
+	show a32 ++ ' '  :
+	show a33
 
 -- |Multiplicate a matrix by a vector (considered as a column).
-multCol :: (Num t) => Matrix3 t -> Vector3 t -> Vector3 t
-multCol m v = Vector3 {
-	a1 = a11 m * a1 v + a12 m * a2 v + a13 m * a3 v,
-	a2 = a21 m * a1 v + a22 m * a2 v + a23 m * a3 v,
-	a3 = a31 m * a1 v + a32 m * a2 v + a33 m * a3 v
+multCol :: Num t => Matrix3 t -> Vector3 t -> Vector3 t
+multCol Matrix3 {..} Vector3 {..} = Vector3 {
+	a1 = a11 * a1 + a12 * a2 + a13 * a3,
+	a2 = a21 * a1 + a22 * a2 + a23 * a3,
+	a3 = a31 * a1 + a32 * a2 + a33 * a3
 	}
-
-
-
diff --git a/Math/ExpPairs/Tests.hs b/Math/ExpPairs/Tests.hs
deleted file mode 100644
--- a/Math/ExpPairs/Tests.hs
+++ /dev/null
@@ -1,20 +0,0 @@
---module Math.ExpPairs.Tests where
-
-import qualified Math.ExpPairs.Tests.RatioInf as RatioInf (testSuite)
-import qualified Math.ExpPairs.Tests.Pair as Pair (testSuite)
-import qualified Math.ExpPairs.Tests.Ivic as Ivic (testSuite)
-import qualified Math.ExpPairs.Tests.MenzerNowak as MenzerNowak (testSuite)
-import qualified Math.ExpPairs.Tests.Matrix3 as Matrix3 (testSuite)
-import qualified Math.ExpPairs.Tests.Kratzel as Kratzel (testSuite)
-import qualified Math.ExpPairs.Tests.LinearForm as LinearForm (testSuite)
-
-main :: IO ()
-main = do
-	print "done"
-	--RatioInf.testSuite
-	--Pair.testSuite
-	--Ivic.testSuite
-	--MenzerNowak.testSuite
-	--Matrix3.testSuite
-	--Kratzel.testSuite
-	--LinearForm.testSuite
diff --git a/exp-pairs.cabal b/exp-pairs.cabal
--- a/exp-pairs.cabal
+++ b/exp-pairs.cabal
@@ -1,5 +1,5 @@
 name:                exp-pairs
-version:             0.1.1.0
+version:             0.1.2.0
 synopsis:            Linear programming over exponent pairs
 description:         Package implements an algorithm to minimize rational objective function over the set of exponent pairs
 homepage:            https://github.com/Bodigrim/exp-pairs
@@ -9,7 +9,7 @@
 maintainer:          andrew.lelechenko@gmail.com
 category:            Math
 build-type:          Simple
-cabal-version:       >=1.8
+cabal-version:       >=1.10
 
 source-repository head
   type:     git
@@ -27,15 +27,24 @@
                        Math.ExpPairs.RatioInf
   build-depends:       base >=4 && <5,
                        memoize >=0.1,
-                       matrix >=0.1
+                       ghc-prim
+  default-language:    Haskell2010
+  ghc-options:         -Wall
 
 test-suite tests
-  ghc-options: -Wall
-  type: exitcode-stdio-1.0
-  main-is: Math/ExpPairs/Tests.hs
+  type:                exitcode-stdio-1.0
+  main-is:             Tests.hs
   build-depends:       base >=4 && <5,
+                       tasty >=0.7,
+                       tasty-quickcheck,
+                       tasty-smallcheck,
+                       tasty-hunit,
                        QuickCheck >=2.4.2,
                        smallcheck >=0.2.1,
                        exp-pairs,
                        memoize >=0.1,
-                       matrix >=0.1
+                       matrix >=0.1,
+                       random
+  hs-source-dirs:      tests
+  default-language:    Haskell2010
+  ghc-options:         -Wall
diff --git a/tests/Tests.hs b/tests/Tests.hs
new file mode 100644
--- /dev/null
+++ b/tests/Tests.hs
@@ -0,0 +1,27 @@
+import qualified LinearForm (testSuite)
+import qualified Matrix3 (testSuite)
+import qualified RatioInf (testSuite)
+import qualified Pair (testSuite)
+
+import qualified Ivic (testSuite)
+import qualified Kratzel (testSuite)
+import qualified MenzerNowak (testSuite)
+
+import Test.Tasty
+
+main :: IO ()
+main = defaultMain tests
+
+tests :: TestTree
+tests = testGroup "Tests"
+	[ LinearForm.testSuite
+	, Matrix3.testSuite
+	, RatioInf.testSuite
+	, Pair.testSuite
+	, Ivic.testSuite
+	, Kratzel.testSuite
+	, MenzerNowak.testSuite
+	]
+
+
+
