{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}{-# OPTIONS_GHC -fno-warn-name-shadowing #-}moduleMath.Root.Finder.Ridders(RiddersMethod,ridders)whereimportMath.Root.Finder-- |@ridders f x1 x2 xacc@: attempt to find a root of a function known to -- lie between x1 and x2, using Ridders' method. The root will be refined-- till its accuracy is +-xacc. If convergence fails, returns the final-- state of the search.ridders::(Orda,Floatinga)=>(a->a)->a->a->a->Either(RiddersMethodaa)ariddersfx1x2xacc=fmapestimateRoot(findRootfx1x2xacc)dataRiddersMethodab=ConvergedRidders!a|RiddersMethod{ridXL::!a,_ridFL::!b,ridXH::!a,_ridFH::!b}deriving(Eq,Show)instance(Floatinga,Orda)=>RootFinderRiddersMethodaawhereinitRootFinderfx1x2|f1<0&&f2<0||f2>0&&f1>0=error"riddersMethod: interval does not bracket a root"|otherwise=RiddersMethodx1f1x2f2wheref1=fx1f2=fx2stepRootFinder_orig@ConvergedRidders{}=origstepRootFinderf(RiddersMethodxlflxhfh)|signNEQfmfNew=finishxNewfNewxmfm|signNEQflfNew=finishxNewfNewxlfl|signNEQfhfNew=finishxNewfNewxhfh|otherwise=error"RiddersMethod: encountered singularity"wherexm=0.5*(xl+xh)fm=fxms=sqrt(fm*fm-fl*fh)xNew=xm+(xm-xl)*((iffl>=fhthenidelsenegate)fm/s)fNew=fxNewsignNEQab=a/=0&&signumb/=signumafinishxlflxhfh|xl==xh=ConvergedRiddersxl|fl==0=ConvergedRiddersxl|fh==0=ConvergedRiddersxh|otherwise=RiddersMethodxlflxhfhestimateRoot(ConvergedRiddersx)=xestimateRootRiddersMethod{ridXL=x}=xestimateErrorConvergedRidders{}=0estimateErrorRiddersMethod{ridXL=xl,ridXH=xh}=xl-xh