Currying和多重积分

orl*_*dpm 5 f# functional-programming currying numerical-methods

我有兴趣学习一种优雅的方法,在函数式编程语言中使用currying来数值评估多个积分.我选择的语言是F#.

如果我想整合f(x,y,z)=8xyz到该区域,[0,1]x[0,1]x[0,1]我首先写下差分形式的三重积分8xyz dx dy dz.在某种意义上,这是三个有序参数的函数:a (float -> float -> float -> float).

我取第一个积分,问题减少到4xy dx dyon 的双积分[0,1]x[0,1].从概念上讲,我们已经把功能变成了一个(float -> float -> float).

在第二个积分之后,我将在单位间隔上取一个积分2x dxa (float -> float).

在三次积分之后,我留下结果,数字1.0.

忽略数字集成的优化,我怎么能简洁地执行它?我想写一些类似的东西:

let diffForm = (fun x y z -> 8 * x * y * z)

let result =
    diffForm
    |> Integrate 0.0 1.0
    |> Integrate 0.0 1.0
    |> Integrate 0.0 1.0
Run Code Online (Sandbox Code Playgroud)

这是否可行,如果可能不切实际?我喜欢这种能够在多大程度上捕捉数学上正在发生的事情的想法.

Fra*_*ank 3

\n

我喜欢这样的想法:这将如何紧密地捕捉数学上正在发生的事情。

\n
\n\n

恐怕您的前提是错误的:管道运算符通过函数链传递一个值,并且与函数组合密切相关。然而,在n维域上积分类似于n嵌套循环,即在您的情况下类似于

\n\n
for x in x_grid_nodes do\n    for y in y_grid_nodes do\n        for z in z_grid_nodes do\n            integral <- integral + ... // details depend on integration scheme\n
Run Code Online (Sandbox Code Playgroud)\n\n

您无法轻松地将其映射到对某个函数的三个独立调用的链Integrate,因此组合integrate x1 x2 >> integrate y1 y2 >> integrate z1 z2实际上不是您集成时所做的事情f。这就是为什么 Tomas\' 解决方案\xe2\x80\x94如果我理解正确(并且我不确定...)\xe2\x80\x94本质上在隐式定义的 3D 网格上评估您的函数并将其传递给集成功能。我怀疑这已经是最接近你原来问题的了。

\n\n

您没有要求它,但如果您确实想在实践中评估n维积分,请研究蒙特卡洛积分,它避免了另一个通常称为“维数灾难”的问题,即所需的数量样本点随着n呈指数增长使用经典积分方案,

\n\n

更新

\n\n

您可以实现迭代集成,但不能使用单个integrate函数,因为集成的每个步骤要集成的函数类型不同(即每个步骤将n元函数转换为 ( n - 1) 元函数):

\n\n
let f = fun x y z -> 8.0 * x * y * z\n\n// numerically integrate f on [x1, x2]\nlet trapRule f x1 x2 = (x2 - x1) * (f x1 + f x2) / 2.0 \n\n// uniform step size for simplicity\nlet h = 0.1\n\n// integrate an unary function f on a given discrete grid\nlet integrate grid f =\n    let mutable integral = 0.0\n    for x1, x2 in Seq.zip grid (Seq.skip 1 grid) do\n        integral <- integral + trapRule f x1 x2\n    integral\n\n// integrate a 3-ary function f with respect to its last argument\nlet integrate3 lower upper f =\n    let grid = seq { lower .. h .. upper }\n    fun x y -> integrate grid (f x y)\n\n// integrate a 2-ary function f with respect to its last argument\nlet integrate2 lower upper f =\n    let grid = seq { lower .. h .. upper }\n    fun x -> integrate grid (f x)\n\n// integrate an unary function f on [lower, upper]\nlet integrate1 lower upper f =\n    integrate (seq { lower .. h .. upper }) f\n
Run Code Online (Sandbox Code Playgroud)\n\n

用你的示例函数f

\n\n
f |> integrate3 0.0 1.0 |> integrate2 0.0 1.0 |> integrate1 0.0 1.0\n
Run Code Online (Sandbox Code Playgroud)\n\n

产量 1.0。

\n