+{-# LANGUAGE DeriveDataTypeable #-}

-- Module : Numeric.Tools.Equation

-- Copyright : (c) 2011 Aleksey Khudyakov

-- Numerical solution of ordinary equations.

module Numeric.Tools.Equation (

+ -- * Equations solversv

-import Numeric.IEEE (epsilon)

+import Numeric.IEEE (epsilon)

+import Control.Applicative

+import Control.Monad (MonadPlus(..), ap)

+import Data.Typeable (Typeable)

+-- | The result of searching for a root of a mathematical function.

+data Root a = NotBracketed

+ -- ^ The function does not have opposite signs when

+ -- evaluated at the lower and upper bounds of the search.

+ -- ^ The search failed to converge to within the given

+ -- error tolerance after the given number of iterations.

+ -- ^ A root was successfully found.

+ deriving (Eq, Read, Show, Typeable)

+instance Functor Root where

+ fmap _ NotBracketed = NotBracketed

+ fmap _ SearchFailed = SearchFailed

+ fmap f (Root a) = Root (f a)

+instance Monad Root where

+ NotBracketed >>= _ = NotBracketed

+ SearchFailed >>= _ = SearchFailed

+instance MonadPlus Root where

+ r@(Root _) `mplus` _ = r

+instance Applicative Root where

+instance Alternative Root where

+-- | Returns either the result of a search for a root, or the default

+-- value if the search failed.

+fromRoot :: a -- ^ Default value.

+ -> Root a -- ^ Result of search for a root.

-- | Solve equation @f(x) = 0@ using bisection method. Function is

solveBisection :: Double -- ^ Required absolute precision

-> (Double,Double) -- ^ Range

-> (Double -> Double) -- ^ Equation

solveBisection eps (a,b) f

- | fa * fb > 0 = Nothing

- | otherwise = Just $ bisectionWorker (abs eps) f a b fa fb

+ | fa * fb > 0 = NotBracketed

+ | otherwise = Root $ bisectionWorker (abs eps) f a b fa fb