-determinant :: (Eq a,
- Ring.C a,
- Vector w a,
- Vector w (v a),
- Vector v a,
- Dim v ~ S r,
- Dim w ~ S t)
- => Mat v w a
- -> a
-determinant m
- | is_triangular m = product [ m !!! (i,i) | i <- [0..(nrows m)-1] ]
- | otherwise = undefined --determinant_recursive m
-
-{-
-determinant_recursive :: forall v w a r c.
- (Eq a,
- Ring.C a,
- Vector w a)
- => Mat (v r) (w c) a
- -> a
-determinant_recursive m
- | (ncols m) == 0 || (nrows m) == 0 = error "don't do that"
- | (ncols m) == 1 && (nrows m) == 1 = m !!! (0,0) -- Base case
- | otherwise =
- sum [ (-1)^(1+(toInteger j)) NP.* (m' 1 j) NP.* (det_minor 1 j)
- | j <- [0..(ncols m)-1] ]
- where
- m' i j = m !!! (i,j)
-
- det_minor :: Int -> Int -> a
- det_minor i j = determinant (minor m i j)
--}
-
--- | Matrix multiplication. Our 'Num' instance doesn't define one, and
--- we need additional restrictions on the result type anyway.
+class (Eq a, Ring.C a) => Determined p a where
+ determinant :: (p a) -> a
+
+instance (Eq a, Ring.C a) => Determined (Mat (S Z) (S Z)) a where
+ determinant (Mat rows) = (V.head . V.head) rows
+
+instance (Eq a,
+ Ring.C a,
+ Arity n,
+ Determined (Mat (S n) (S n)) a)
+ => Determined (Mat (S (S n)) (S (S n))) a where
+ -- | The recursive definition with a special-case for triangular matrices.
+ --
+ -- Examples:
+ --
+ -- >>> let m = fromList [[1,2],[3,4]] :: Mat2 Int
+ -- >>> determinant m
+ -- -1
+ --
+ determinant m
+ | is_triangular m = product [ m !!! (i,i) | i <- [0..(nrows m)-1] ]
+ | otherwise = determinant_recursive
+ where
+ m' i j = m !!! (i,j)
+
+ det_minor i j = determinant (minor m i j)
+
+ determinant_recursive =
+ sum [ (-1)^(toInteger j) NP.* (m' 0 j) NP.* (det_minor 0 j)
+ | j <- [0..(ncols m)-1] ]
+
+
+
+-- | Matrix multiplication.