你当然可以做和你已经实现的一样的事情,只是用多元扰动代替。但首先,正如您应该始终使用顶级函数一样,添加类型签名:
deriv :: (Double -> Double) -> Double -> Double
这可能不是最通用的签名,但可能对您需要的所有内容都足够通用。我会打电话的
type ℝ = Double
以下为简洁起见,即
deriv :: (ℝ -> ℝ) -> ℝ -> ℝ
现在你想要的是,例如在ℝ²中
grad :: ((ℝ,ℝ) -> ℝ) -> (ℝ,ℝ) -> (ℝ,ℝ)
grad f (x,y) = ((f (x+h,y) - f (x,y)) / h, (f (x,y+h) - f (x,y)) / h)
where h = 0.00001
不得不单独写出组件并针对特定维向量空间进行定义是很尴尬的。 generic way 这样做:
import Data.VectorSpace
import Data.Basis
grad :: (HasBasis v, Scalar v ~ ℝ) => (v -> ℝ) -> v -> v
grad f x = recompose [ (e, (f (x ^+^ h*^basisValue b) - f x) ^/ h)
| (e,_) <- decompose x ]
where h = 0.00001
请注意,这种预先选择的步骤-有限微分始终是在高阶项的不准确性和浮点错误之间进行权衡,所以一定要检查自动微分。