{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {- | Abstraction of normed vector spaces -} module Algebra.NormedSpace.Euclidean where import NumericPrelude.Base import NumericPrelude.Numeric (sqr, abs, zero, (+), sum, Float, Double, Int, Integer, ) import qualified Prelude as P import qualified Number.Ratio as Ratio import qualified Algebra.PrincipalIdealDomain as PID import qualified Algebra.Algebraic as Algebraic import qualified Algebra.Absolute as Absolute import qualified Algebra.Module as Module import qualified Data.Complex as Complex98 import qualified Data.Foldable as Fold {-| Helper class for 'C' that does not need an algebraic type @a@. Minimal definition: 'normSqr' -} class (Absolute.C a, Module.C a v) => Sqr a v where {-| Square of the Euclidean norm of a vector. This is sometimes easier to implement. -} normSqr :: v -> a -- normSqr = sqr . norm {- | Default definition for 'normSqr' that is based on 'Fold.Foldable' class. -} {-# INLINE normSqrFoldable #-} normSqrFoldable :: (Sqr a v, Fold.Foldable f) => f v -> a normSqrFoldable = Fold.foldl (\a v -> a + normSqr v) zero {- | Default definition for 'normSqr' that is based on 'Fold.Foldable' class and the argument vector has at least one component. -} {-# INLINE normSqrFoldable1 #-} normSqrFoldable1 :: (Sqr a v, Fold.Foldable f, Functor f) => f v -> a normSqrFoldable1 = Fold.foldl1 (+) . fmap normSqr {-| A vector space equipped with an Euclidean or a Hilbert norm. Minimal definition: 'norm' -} class (Sqr a v) => C a v where {-| Euclidean norm of a vector. -} norm :: v -> a defltNorm :: (Algebraic.C a, Sqr a v) => v -> a defltNorm = Algebraic.sqrt . normSqr {-* Instances for atomic types -} instance Sqr Float Float where normSqr = sqr instance C Float Float where norm = abs instance Sqr Double Double where normSqr = sqr instance C Double Double where norm = abs instance Sqr Int Int where normSqr = sqr instance C Int Int where norm = abs instance Sqr Integer Integer where normSqr = sqr instance C Integer Integer where norm = abs {-* Instances for composed types -} instance (Absolute.C a, PID.C a) => Sqr (Ratio.T a) (Ratio.T a) where normSqr = sqr instance (Sqr a v0, Sqr a v1) => Sqr a (v0, v1) where normSqr (x0,x1) = normSqr x0 + normSqr x1 instance (Algebraic.C a, Sqr a v0, Sqr a v1) => C a (v0, v1) where norm = defltNorm instance (Sqr a v0, Sqr a v1, Sqr a v2) => Sqr a (v0, v1, v2) where normSqr (x0,x1,x2) = normSqr x0 + normSqr x1 + normSqr x2 instance (Algebraic.C a, Sqr a v0, Sqr a v1, Sqr a v2) => C a (v0, v1, v2) where norm = defltNorm instance (Sqr a v) => Sqr a [v] where normSqr = sum . map normSqr instance (Algebraic.C a, Sqr a v) => C a [v] where norm = defltNorm instance (Sqr a v, P.RealFloat v) => Sqr a (Complex98.Complex v) where normSqr (x0 Complex98.:+ x1) = normSqr x0 + normSqr x1 instance (Algebraic.C a, Sqr a v, P.RealFloat v) => C a (Complex98.Complex v) where norm = defltNorm