]> gitweb.michael.orlitzky.com - numerical-analysis.git/commitdiff
Add a Normed instance for (Vec n a).
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 2 Feb 2014 23:46:48 +0000 (18:46 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 2 Feb 2014 23:46:48 +0000 (18:46 -0500)
src/Normed.hs

index f339ebfd6757a86123f8111c4cb1bb7f5ef35534..6f34a8dca406c13393896179b6b08c023874e9a3 100644 (file)
@@ -8,12 +8,22 @@ where
 
 import BigFloat
 
-import NumericPrelude hiding (abs)
-import Algebra.Absolute (abs)
+import NumericPrelude hiding ( abs )
+import Algebra.Absolute ( abs )
 import qualified Algebra.Absolute as Absolute
 import qualified Algebra.Algebraic as Algebraic
+import Algebra.Algebraic ( root )
 import qualified Algebra.RealField as RealField
 import qualified Algebra.ToInteger as ToInteger
+import qualified Algebra.ToRational as ToRational ( C )
+import Data.Vector.Fixed ( S, Z )
+import qualified Data.Vector.Fixed as V (
+  Arity,
+  map,
+  maximum )
+import Data.Vector.Fixed.Boxed ( Vec )
+
+import Linear.Vector ( element_sum )
 
 class Normed a where
   norm_p :: (ToInteger.C c, Algebraic.C b, Absolute.C b) => c -> a -> b
@@ -43,3 +53,38 @@ instance Normed Float where
 instance Normed Double where
   norm_p _ = abs . fromRational' . toRational
   norm_infty = abs . fromRational' . toRational
+
+
+-- | 'Normed' instance for vectors of length zero. These are easy.
+instance Normed (Vec Z a) where
+  norm_p _ = const (fromInteger 0)
+  norm_infty = const (fromInteger 0)
+
+
+-- | 'Normed' instance for vectors of length greater than zero. We
+--   need to know that the length is non-zero in order to invoke
+--   V.maximum. We will generally be working with n-by-1 /matrices/
+--   instead of vectors, but sometimes it's convenient to have these
+--   instances anyway.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed (mk3)
+--   >>> import Linear.Vector (Vec3)
+--   >>> let b = mk3 1 2 3 :: Vec3 Double
+--   >>> norm_p 1 b :: Double
+--   6.0
+--   >>> norm b == sqrt 14
+--   True
+--   >>> norm_infty b :: Double
+--   3.0
+--
+instance (V.Arity n, Absolute.C a, ToRational.C a, Ord a)
+         => Normed (Vec (S n) a) where
+  norm_p p x =
+    (root p') $ element_sum $ V.map element_function x
+    where
+      element_function y = fromRational' $ (toRational y)^p'
+      p' = toInteger p
+
+  norm_infty x = fromRational' $ toRational $ V.maximum $ V.map abs x