【问题标题】:Partial Derivatives in HaskellHaskell 中的偏导数
【发布时间】:2018-01-11 21:06:19
【问题描述】:

不久前,一位朋友想要一个可以使用牛顿法求解函数根的程序的帮助,为此我自然需要某种方法来数值计算函数的导数,这就是我想出的:

deriv f x = (f (x+h) - f x) / h where h = 0.00001

牛顿的方法很容易实现,而且效果很好。但现在我开始怀疑 - 有什么方法可以使用这个函数以数值方式求解偏导数,还是需要一个完整的 CAS?我会发布我的尝试,但我完全不知道该怎么做。

请记住,我是 Haskell 的新手。谢谢!

【问题讨论】:

    标签: haskell calculus


    【解决方案1】:

    你当然可以做和你已经实现的一样的事情,只是用多元扰动代替。但首先,正如您应该始终使用顶级函数一样,添加类型签名:

    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
    

    请注意,这种预先选择的步骤-有限微分始终是在高阶项的不准确性和浮点错误之间进行权衡,所以一定要检查自动微分。

    【讨论】:

      【解决方案2】:

      这被称为automatic differentiation,在 Haskell 的这个领域有很多非常巧妙的工作,虽然我不知道它有多容易访问。

      来自维基页面:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多