在将向量空间包用于导数塔时(请参阅导数塔),我遇到了对积分进行微分的需要。从数学上很清楚如何实现这一点:
f(x) = int g(y) dy from 0 to x
有一个功能
g : R -> R
例如。
关于 x 的导数是:
f'(x) = g(x)
我试图通过首先定义一个“集成”类来获得这种行为
class Integration a b where
--standard integration function
integrate :: (a -> b) -> a -> a -> b
一个基本的例子是
instance Integration Double Double where
integrate f a b = fst $ integrateQAGS prec 1000 f a b
integrateQAGS
来自hmatrix _
问题在于代表衍生品塔的值 b:
instance Integration Double (Double :> (NC.T Double)) where
integrate = integrateD
NC.T
来自 Numeric.Complex (numeric-prelude)。该函数integrateD
定义如下(但错误):
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 (numeric-prelude) 乘法
我可以轻松地将此功能与上述功能集成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 ...