]> gitweb.michael.orlitzky.com - numerical-analysis.git/blobdiff - src/Linear/Iteration.hs
Clean up imports everywhere.
[numerical-analysis.git] / src / Linear / Iteration.hs
index 89f2f0c0eab7788a088642afd81e98525478e610..06d30a802aa55717b6a9ec45b42c69a8b8f8b473 100644 (file)
@@ -1,24 +1,42 @@
+{-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
 
 -- | Classical iterative methods to solve the system Ax = b.
 
-module Linear.Iteration
+module Linear.Iteration (
+  gauss_seidel_iteration,
+  gauss_seidel_iterations,
+  gauss_seidel_method,
+  jacobi_iteration,
+  jacobi_iterations,
+  jacobi_method,
+  rayleigh_quotient,
+  sor_iteration,
+  sor_iterations,
+  sor_method )
 where
 
-import Data.List (find)
-import Data.Maybe (fromJust)
-import Data.Vector.Fixed (Arity, N1, S)
-import NumericPrelude hiding ((*))
-import qualified Algebra.Algebraic as Algebraic
-import qualified Algebra.Field as Field
-import qualified Algebra.RealField as RealField
-import qualified Algebra.ToRational as ToRational
-import qualified Prelude as P
+import Data.List ( find )
+import Data.Maybe ( fromJust )
+import Data.Vector.Fixed ( Arity, N1, S )
+import NumericPrelude hiding ( (*) )
+import qualified Algebra.Algebraic as Algebraic ( C )
+import qualified Algebra.Field as Field ( C )
+import qualified Algebra.RealField as RealField ( C )
+import qualified Algebra.ToRational as ToRational ( C )
+
+import Linear.Matrix (
+  Mat(..),
+  (!!!),
+  (*),
+  diagonal_part,
+  dot,
+  lt_part_strict,
+  transpose )
+import Linear.System ( forward_substitute )
+import Normed ( Normed(..) )
 
-import Linear.Matrix
-import Linear.System
-import Normed
 
 -- | A generalized implementation for Jacobi, Gauss-Seidel, etc. All
 --   that we really need to know is how to construct the matrix M, so we
@@ -97,6 +115,8 @@ gauss_seidel_iterations matrix b =
 --
 --   Examples:
 --
+--   >>> import Linear.Matrix ( Mat2, fromList, vec2d )
+--
 --   >>> let m  = fromList [[4,2],[2,2]] :: Mat2 Double
 --   >>> let x0 = vec2d (0, 0::Double)
 --   >>> let b  = vec2d (1, 1::Double)
@@ -131,6 +151,8 @@ jacobi_iterations matrix b =
 --
 --   Examples:
 --
+--   >>> import Linear.Matrix ( Mat2, fromList, vec2d )
+--
 --   >>> let m  = fromList [[4,2],[2,2]] :: Mat2 Double
 --   >>> let x0 = vec2d (0, 0::Double)
 --   >>> let b  = vec2d (1, 1::Double)
@@ -160,6 +182,8 @@ jacobi_method =
 --
 --   Examples:
 --
+--   >>> import Linear.Matrix ( Mat2, fromList, vec2d )
+--
 --   >>> let m  = fromList [[4,2],[2,2]] :: Mat2 Double
 --   >>> let x0 = vec2d (0, 0::Double)
 --   >>> let b  = vec2d (1, 1::Double)
@@ -190,6 +214,8 @@ gauss_seidel_method =
 --
 --   Examples:
 --
+--   >>> import Linear.Matrix ( Mat2, fromList, vec2d )
+--
 --   >>> let m  = fromList [[4,2],[2,2]] :: Mat2 Double
 --   >>> let x0 = vec2d (0, 0::Double)
 --   >>> let b  = vec2d (1, 1::Double)
@@ -261,3 +287,30 @@ classical_method iterations_function matrix b x0 epsilon =
 
     error_small_enough :: (Mat m N1 a, Mat m N1 a, b)-> Bool
     error_small_enough (_,_,err) = err < epsilon
+
+
+
+-- | Compute the Rayleigh quotient of  @matrix@ and @vector@.
+--
+--   Examples:
+--
+--   >>> import Linear.Matrix ( Mat2, fromList, vec2d )
+--
+--   >>> let m = fromList [[3,1],[1,2]] :: Mat2 Rational
+--   >>> let v = vec2d (1, 1::Rational)
+--   >>> rayleigh_quotient m v
+--   7 % 2
+--
+rayleigh_quotient :: (RealField.C a,
+                      Arity m,
+                      Arity n,
+                      m ~ S n)
+                  => (Mat m m a)
+                  -> (Mat m N1 a)
+                  -> a
+rayleigh_quotient matrix vector =
+  (vector `dot` (matrix * vector)) / (norm_squared vector)
+  where
+    -- We don't use the norm function here to avoid the algebraic
+    -- requirement on our field.
+    norm_squared v = ((transpose v) * v) !!! (0,0)