如何将函数应用于浮点数组?

时间:2010-02-24 19:04:25

标签: f#

假设我有n个数组,其中n是一个变量(某个数字大于2,通常小于10)。

每个数组都有k个元素。

我还有一个长度为n的数组,其中包含一组权重,这些权重决定了我如何线性组合所有数组。

我正在尝试创建一个高性能的高阶函数,以便在F#中组合这些数组。

我该如何做到这一点,以便我得到一个函数,它接受一个数组数组(arrs是一个样本),一个权重数组(权重),然后根据权重计算一个加权和?

let weights = [|.6;;.3;.1|]

let arrs = [| [|.0453;.065345;.07566;1.562;356.6|] ; 
              [|.0873;.075565;.07666;1.562222;3.66|] ; 
              [|.06753;.075675;.04566;1.452;3.4556|] |]

感谢任何想法。

2 个答案:

答案 0 :(得分:6)

这是一个解决方案:

let combine weights arrs =
  Array.map2 (fun w -> Array.map ((*) w)) weights arrs 
  |> Array.reduce (Array.map2 (+))

修改

这里有一些(非常需要的)解释这是如何工作的。从逻辑上讲,我们希望执行以下操作:

  1. 将每个砝码应用于相应的行。
  2. 将经过重量调整的行添加在一起。
  3. 上面两行就是这样做的。

    1. 我们使用Array.map2函数来组合相应的权重和行;我们将它们组合在一起的方法是将行中的每个元素乘以权重,这通过内部Array.map来实现。
    2. 现在我们有一系列加权行,需要将它们加在一起。我们可以一步一步地保持运行总和,依次添加每个数组。我们逐点求和两个数组的方法是再次使用Array.map2,使用(+)作为组合每个元素的函数。我们将它包装在Array.reduce中,依次从第一行开始依次将此添加函数应用于每一行。
    3. 希望这是一个相当优雅的解决问题的方法,尽管无点的风格无疑使得它有点棘手。但请注意,它并不是特别高效;进行就地更新而不是使用mapmap2reduce的每个应用程序创建新数组会更有效。不幸的是,标准库不包含这些操作的良好类似物,这些操作就地工作。但是,创建这样的类似物会相对容易,而且它们的使用方式几乎和我在这里完全相同。

答案 1 :(得分:1)

这样的事情对我有用:

let weights = [|0.6;0.3;0.1|]

let arrs = [| [|0.0453;0.065345;0.07566;1.562;356.6|] ; 
              [|0.0873;0.075565;0.07666;1.562222;3.66|] ; 
              [|0.06753;0.075675;0.04566;1.452;3.4556|] |]

let applyWeight x y = x * y

let rotate (arr:'a[][]) = 
    Array.map (fun y -> (Array.map (fun x -> arr.[x].[y])) [|0..arr.Length - 1|]) [|0..arr.[0].Length - 1|]

let weightedarray = Array.map (fun x -> Array.map(applyWeight (fst x)) (snd x)) (Array.zip weights arrs)

let newarrs = Array.map Array.sum (rotate weightedarray)

printfn "%A" newarrs

顺便说一下..浮点值前面的0是必要的。