From: Michael Orlitzky Date: Sun, 2 Feb 2014 17:34:42 +0000 (-0500) Subject: Add the Frobenius norm to Linear.Matrix. X-Git-Url: https://gitweb.michael.orlitzky.com/?a=commitdiff_plain;h=af25e6f32f6787a747be63093adc10915ad60068;p=numerical-analysis.git Add the Frobenius norm to Linear.Matrix. --- diff --git a/src/Linear/Matrix.hs b/src/Linear/Matrix.hs index c0f56b3..66b22f9 100644 --- a/src/Linear/Matrix.hs +++ b/src/Linear/Matrix.hs @@ -2,6 +2,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE RebindableSyntax #-} @@ -34,6 +35,7 @@ import Data.Vector.Fixed ( ) import qualified Data.Vector.Fixed as V ( and, + foldl, fromList, head, length, @@ -457,7 +459,31 @@ instance (Algebraic.C a, fromRational' $ toRational $ V.maximum $ V.map V.maximum rows +-- | Compute the Frobenius norm of a matrix. This essentially treats +-- the matrix as one long vector containing all of its entries (in +-- any order, it doesn't matter). +-- +-- Examples: +-- +-- >>> let m = fromList [[1, 2, 3],[4,5,6],[7,8,9]] :: Mat3 Double +-- >>> frobenius_norm m == sqrt 285 +-- True +-- +-- >>> let m = fromList [[1, -1, 1],[-1,1,-1],[1,-1,1]] :: Mat3 Double +-- >>> frobenius_norm m == 3 +-- True +-- +frobenius_norm :: (Algebraic.C a, Ring.C a) => Mat m n a -> a +frobenius_norm (Mat rows) = + sqrt $ vsum $ V.map row_sum rows + where + -- | The \"sum\" function defined in fixed-vector requires a 'Num' + -- constraint whereas we want to use the classes from + -- numeric-prelude. + vsum = V.foldl (+) (fromInteger 0) + -- | Square and add up the entries of a row. + row_sum = vsum . V.map (^2) -- Vector helpers. We want it to be easy to create low-dimension