gpt4 book ai didi

f# - 柯里化(Currying)和多重积分

转载 作者:行者123 更新时间:2023-12-04 19:11:41 24 4
gpt4 key购买 nike

我有兴趣学习一种优雅的方法来使用函数式编程语言中的柯里化(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 的二重积分在 [0,1]x[0,1] .从概念上讲,我们将函数柯里化(Currying)为 (float -> float -> float) .

在第二个积分之后,我只剩下 2x dx 的积分了, 一个 (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

如果可能不切实际,这是可行的吗?我喜欢这样的想法,即这将在数学上捕捉到正在发生的事情。

最佳答案

I like the idea of how closely this would capture what is going on mathematically.



恐怕您的前提是错误的:管道运算符通过一系列函数将值线程化,并且与函数组合密切相关。然而,在 n 维域上积分类似于 n 嵌套循环,即在您的情况下类似于
for x in x_grid_nodes do
for y in y_grid_nodes do
for z in z_grid_nodes do
integral <- integral + ... // details depend on integration scheme

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

您没有要求它,但如果您确实想在实践中评估 n 维积分,请查看 Monte Carlo 积分,它避免了另一个通常称为“维度诅咒”的问题,即所需的数量使用经典积分方案,样本点随 n 呈指数增长。

更新

您可以实现迭代集成,但不能使用单个 integrate函数,因为要集成的函数的类型对于集成的每一步都不同(即每一步都将 n 元函数转换为 (n - 1) 元函数):
let f = fun x y z -> 8.0 * x * y * z

// numerically integrate f on [x1, x2]
let trapRule f x1 x2 = (x2 - x1) * (f x1 + f x2) / 2.0

// uniform step size for simplicity
let h = 0.1

// integrate an unary function f on a given discrete grid
let integrate grid f =
let mutable integral = 0.0
for x1, x2 in Seq.zip grid (Seq.skip 1 grid) do
integral <- integral + trapRule f x1 x2
integral

// integrate a 3-ary function f with respect to its last argument
let integrate3 lower upper f =
let grid = seq { lower .. h .. upper }
fun x y -> integrate grid (f x y)

// integrate a 2-ary function f with respect to its last argument
let integrate2 lower upper f =
let grid = seq { lower .. h .. upper }
fun x -> integrate grid (f x)

// integrate an unary function f on [lower, upper]
let integrate1 lower upper f =
integrate (seq { lower .. h .. upper }) f

使用您的示例函数 f
f |> integrate3 0.0 1.0 |> integrate2 0.0 1.0 |> integrate1 0.0 1.0

产生 1.0。

关于f# - 柯里化(Currying)和多重积分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14366591/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com