{-| Module : Control.ERNet.Blocks.Real.Basic Description : basic processes for processing reals via intervals Copyright : (c) Michal Konecny License : BSD3 Maintainer : mik@konecny.aow.cz Stability : experimental Portability : portable -} module Control.ERNet.Blocks.Real.Basic ( rateRProcess, rateRsProcess ) where import Control.ERNet.Foundations.Protocol import Control.ERNet.Foundations.Protocol.StandardCombinators import qualified Control.ERNet.Foundations.Channel as CH import Control.ERNet.Foundations.Process import Control.ERNet.Blocks.Basic import Control.ERNet.Blocks.Real.Protocols import qualified Data.Number.ER.Real.Approx as RA import qualified Data.Number.ER.Real.Approx.Elementary as RAEL import Data.Typeable {-| A process passing on information about a real number, trying to improve the convergence rate in successive queries. Each query may refer to a previous query. When it does, the query will not be answered until either: * the information about the number has improved by the desired amount since last time * the number of queries made in response to this query has reached the given limit -} rateRProcess :: (CH.Channel sIn sOut sInAnyProt sOutAnyProt, RAEL.ERApproxElementary ra, Typeable ra) => ERProcessName {-^ process identifier (string) -} -> Rational {-^ desired ratio of improvement -} -> Int {-^ maximum number of attempts to reach desired improvement -} -> ra {-^ sample approximation to aid typechecking -} -> ERProcess sInAnyProt sOutAnyProt rateRProcess defName desiredImpr maxAttepts sampleRA = rateProcess defName goodEnough maxAttepts chtpRC where chtpRC = chTChanges $ chTIx $ chtpRNoIx chtpRNoIx = chTReal sampleRA goodEnough _ QAChangesAGivenUp = True goodEnough QAChangesAGivenUp _ = True goodEnough (QAChangesANew (QAIxA (QARealA prevRA))) (QAChangesANew (QAIxA (QARealA newRA))) = case RA.compareReals (impr) (fromRational desiredImpr) of Just LT -> False _ -> True where (_, impr) = RA.intersectMeasureImprovement 20 prevRA newRA _ = prevRA == sampleRA {-| A process passing on information about a list of real numbers, trying to improve the convergence rate in successive queries. Each query may refer to a previous query. When it does, the query will not be answered until either: * the information about the tuple has improved by the desired amount since last time * the number of queries made in response to this query has reached the given limit -} rateRsProcess :: (CH.Channel sIn sOut sInAnyProt sOutAnyProt, RAEL.ERApproxElementary ra, Typeable ra) => ERProcessName {-^ process identifier (string) -} -> Rational {-^ desired ratio of improvement -} -> Int {-^ maximum number of attempts to reach desired improvement -} -> ra {-^ sample approximation to aid typechecking -} -> ERProcess sInAnyProt sOutAnyProt rateRsProcess defName desiredImpr maxAttepts sampleRA = rateProcess defName goodEnough maxAttepts chtpRsC where chtpRsC = chTChanges $ chTIx $ chTList chtpRNoIx chtpRNoIx = chTReal sampleRA -- Just (QAChangesANew (QAIxA (QAListASingle (QARealA sampleRA)))) = cast a goodEnough _ QAChangesAGivenUp = True goodEnough QAChangesAGivenUp _ = True goodEnough (QAChangesANew (QAIxA (QAListA prevAs))) (QAChangesANew (QAIxA (QAListA newAs))) = case RA.compareReals (impr) (fromRational desiredImpr) of Just LT -> False _ -> True where impr = foldl max 1 $ zipWith getImprAs prevAs newAs getImprAs (QARealA prevRA) (QARealA newRA) = snd $ RA.intersectMeasureImprovement 20 prevRA newRA where _ = prevRA == sampleRA