module Data.Number.ER.RnToRm.UnitDom.ChebyshevBase.Polynom.Compose
where
import Data.Number.ER.RnToRm.UnitDom.ChebyshevBase.Polynom.Basic
import Data.Number.ER.RnToRm.UnitDom.ChebyshevBase.Polynom.Ring
import Data.Number.ER.RnToRm.UnitDom.ChebyshevBase.Polynom.Bounds
import Data.Number.ER.RnToRm.UnitDom.ChebyshevBase.Polynom.Enclosure
import qualified Data.Number.ER.Real.Approx as RA
import qualified Data.Number.ER.Real.Base as B
import qualified Data.Number.ER.Real.DomainBox as DBox
import Data.Number.ER.Real.DomainBox (VariableID(..), DomainBox, DomainBoxMappable, DomainIntBox)
import Data.Number.ER.Misc
import qualified Data.Map as Map
enclCompose ::
(B.ERRealBase b, RealFrac b, DomainBox box varid Int, Ord box) =>
Int ->
Int ->
ERChebPoly box b ->
varid ->
(ERChebPoly box b, ERChebPoly box b)
->
(ERChebPoly box b, ERChebPoly box b)
enclCompose maxDegree maxSize p@(ERChebPoly coeffs) substVar substEncl =
result
where
result =
Map.fold (+:) (enclConst 0) $ Map.mapWithKey evalDegree degreePolynomialMap
degreePolynomialMap =
Map.foldWithKey extractTerm Map.empty coeffs
extractTerm term c prevPolynomMap =
Map.insertWith Map.union substVarDegree (Map.singleton termNoSubstVar c) prevPolynomMap
where
substVarDegree = DBox.findWithDefault 0 substVar term
termNoSubstVar = DBox.delete substVar term
evalDegree degree degreeCoeffs =
enclMultiply maxDegree maxSize (substPolyDegrees !! degree) (chplNeg degreePoly, degreePoly)
where
degreePoly = ERChebPoly degreeCoeffs
substPolyDegrees =
enclEvalTs maxSize maxDegree substEncl
enclComposeMany ::
(B.ERRealBase b, RealFrac b, DomainBox box varid Int, Ord box) =>
Int ->
Int ->
ERChebPoly box b ->
Map.Map varid (ERChebPoly box b, ERChebPoly box b)
->
(ERChebPoly box b, ERChebPoly box b)
enclComposeMany maxDegree maxSize p@(ERChebPoly coeffs) substitutions =
result
where
result =
foldl (+:) (enclConst 0) $ map evalTerm $ Map.toList coeffs
evalTerm (term, c) =
enclScale maxDegree maxSize c $
foldl (enclMultiply maxDegree maxSize) (enclConst 1) $
map evalVar $ DBox.toList term
evalVar (varID, degree) =
case Map.lookup varID substDegrees of
Nothing ->
(chplNeg varPoly, varPoly)
Just pvDegrees ->
pvDegrees !! degree
where
varPoly =
ERChebPoly $ Map.singleton (DBox.singleton varID degree) 1
substDegrees =
Map.map mkPVDegrees substitutions
mkPVDegrees pvEncl =
enclEvalTs maxSize maxDegree pvEncl