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 dy
on 的双积分[0,1]x[0,1]
.从概念上讲,我们已经把功能变成了一个(float -> float -> float)
.
在第二个积分之后,我将在单位间隔上取一个积分2x dx
a (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)
这是否可行,如果可能不切实际?我喜欢这种能够在多大程度上捕捉数学上正在发生的事情的想法.
\n\n\n我喜欢这样的想法:这将如何紧密地捕捉数学上正在发生的事情。
\n
恐怕您的前提是错误的:管道运算符通过函数链传递一个值,并且与函数组合密切相关。然而,在n维域上积分类似于n嵌套循环,即在您的情况下类似于
\n\nfor 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您可以实现迭代集成,但不能使用单个integrate
函数,因为集成的每个步骤要集成的函数类型不同(即每个步骤将n元函数转换为 ( n - 1) 元函数):
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
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