acos theta
where
theta = (v1 `dot` v2) / norms
- norms = (norm_p (2 :: Integer) v1) * (norm_p (2 :: Integer) v2)
+ norms = (norm v1) * (norm v2)
-- | Convenience function for creating 2d vectors.
import Data.Number.BigFloat
-class Normed a where
+-- Since the norm is defined on a vector space, we should be able to
+-- add and subtract anything on which a norm is defined. Of course
+-- 'Num' is a bad choice here, but we really prefer to use the normal
+-- addition and subtraction operators.
+class (Num a) => Normed a where
norm_p :: (Integral c, RealFrac b) => c -> a -> b
norm_infty :: RealFrac b => a -> b
+ -- | The "usual" norm. Defaults to the Euclidean norm.
+ norm :: RealFrac b => a -> b
+ norm = norm_p (2 :: Integer)
+
-- Define instances for common numeric types.
instance Normed Integer where
norm_p _ = fromInteger
import Data.List (find)
-import Vector
+import Normed
has_root :: (Fractional a, Ord a, Ord b, Num b)
--
-- We also return the number of iterations required.
--
-fixed_point_with_iterations :: (Vector a, RealFrac b)
+fixed_point_with_iterations :: (Normed a, RealFrac b)
=> (a -> a) -- ^ The function @f@ to iterate.
-> b -- ^ The tolerance, @epsilon@.
-> a -- ^ The initial value @x0@.
xn = fixed_point_iterations f x0
xn_plus_one = tail xn
- abs_diff v w = norm_2 (v - w)
+ abs_diff v w = norm (v - w)
-- The nth entry in this list is the absolute value of x_{n} -
-- x_{n+1}.
import Data.List (find)
-import Vector
+import Normed
import qualified Roots.Fast as F
-- at x0. We delegate to the version that returns the number of
-- iterations and simply discard the number of iterations.
--
-fixed_point :: (Vector a, RealFrac b)
+fixed_point :: (Normed a, RealFrac b)
=> (a -> a) -- ^ The function @f@ to iterate.
-> b -- ^ The tolerance, @epsilon@.
-> a -- ^ The initial value @x0@.
-- the function @f@ with the search starting at x0 and tolerance
-- @epsilon@. We delegate to the version that returns the number of
-- iterations and simply discard the fixed point.
-fixed_point_iteration_count :: (Vector a, RealFrac b)
+fixed_point_iteration_count :: (Normed a, RealFrac b)
=> (a -> a) -- ^ The function @f@ to iterate.
-> b -- ^ The tolerance, @epsilon@.
-> a -- ^ The initial value @x0@.
--
-- This is used to determine the rate of convergence.
--
-fixed_point_error_ratios :: (Vector a, RealFrac b)
+fixed_point_error_ratios :: (Normed a, RealFrac b)
=> (a -> a) -- ^ The function @f@ to iterate.
-> a -- ^ The initial value @x0@.
-> a -- ^ The true solution, @x_star@.
zipWith (/) en_plus_one en_exp
where
xn = F.fixed_point_iterations f x0
- en = map (\x -> norm_2 (x_star - x)) xn
+ en = map (\x -> norm (x_star - x)) xn
en_plus_one = tail en
en_exp = map (^p) en
module TwoTuple
where
-import Vector
+import Normed
data TwoTuple a = TwoTuple a a
instance Functor TwoTuple where
f `fmap` (TwoTuple x1 y1) = TwoTuple (f x1) (f y1)
-instance (RealFloat a) => Vector (TwoTuple a) where
+instance (RealFloat a) => Normed (TwoTuple a) where
-- The standard Euclidean 2-norm. We need RealFloat for the square
-- root.
- norm_2 (TwoTuple x y) = fromRational $ toRational (sqrt(x^2 + y^2))
+ norm (TwoTuple x y) = fromRational $ toRational (sqrt(x^2 + y^2))
-- The infinity norm, i.e. the maximum entry.
norm_infty (TwoTuple x y) =
+++ /dev/null
-{-# LANGUAGE FlexibleInstances #-}
-
--- | The 'Vector' class represents elements of a normed vector
--- space. We define instances for all common numeric types.
-module Vector
-where
-
-import Data.Number.BigFloat
-
-class (Num a) => Vector a where
- norm_2 :: RealFrac b => a -> b
- norm_infty :: RealFrac b => a -> b
-
--- Define instances for common numeric types.
-instance Vector Integer where
- norm_2 = fromInteger
- norm_infty = fromInteger
-
-instance Vector Rational where
- norm_2 = fromRational
- norm_infty = fromRational
-
-instance Epsilon e => Vector (BigFloat e) where
- norm_2 = fromRational . toRational
- norm_infty = fromRational . toRational
-
-instance Vector Double where
- norm_2 = fromRational . toRational
- norm_infty = fromRational . toRational