When using vector-space package for derivative towers (see derivative towers ). I am faced with the need to differentiate the integrals. From mathematics itβs very clear how to achieve this:
f(x) = int g(y) dy from 0 to x
with function
g : R -> R
eg.
The derivative with respect to x will be:
f'(x) = g(x)
I tried to get this behavior by first defining the Integration class
class Integration a b where
--standard integration function
integrate :: (a -> b) -> a -> a -> b
base instance
instance Integration Double Double where
integrate f a b = fst $ integrateQAGS prec 1000 f a b
with integrateQAGSfrom hmatrix
the problem arises with the values ββof b, which are towers of derivatives:
instance Integration Double (Double :> (NC.T Double)) where
integrate = integrateD
NC.T- from Numeric.Complex (prelude number). The function is integrateDdefined as follows (but incorrectly):
integrateD ::(Integration a b, HasTrie (Basis a), HasBasis a, AdditiveGroup b) => (a -> a :> b) -> a -> a -> (a :> b)
integrateD f l u = D (integrate (powVal . f) l u) (derivative $ f u)
, , , . , , f u. a :> b :
data a :> b = D { powVal :: b, derivative :: a :-* (a :> b) }
, derivative. ,
:
Integration Double (NC.T Double):
instance Integration Double (NC.T Double) where
integrate f a b = bc $ (\g -> integrate g a b) <$> [NC.real . f, NC.imag . f]
where bc (x:y:[]) = x NC.+: y
, :
,
f(x) = exp(2*x)*sin(x)
>let f = \x -> (Prelude.exp ((pureD 2.0) AR.* (idD x))) * (sin (idD x)) :: Double :> Double
(AR. *) Algebra.Ring(-)
integrateD:
>integrateD f 0 1 :: Double :> Double
D 1.888605715258933 ...
f:
f'(x) = 2*exp(2*x)*sin(x)+exp(2*x)*cos(x)
0 pi/2 1 :
> derivAtBasis (f 0.0) ()
D 1.0 ...
> derivAtBasis (f (pi AF./ 2)) ()
D 46.281385265558534 ...
, , f
> derivAtBasis (integrate f 0 (pi AF./ 2)) ()
D 46.281385265558534 ...
:
> f (pi AF./ 2)
D 23.140692632779267 ...