【问题标题】:Broadcasting operations in MathNetMathNet 中的广播操作
【发布时间】:2016-07-03 18:01:17
【问题描述】:

假设我有以下数据:

var1,var2,var3
0.942856823,0.568425866,0.325885379
1.227681099,1.335672206,0.925331054
1.952671045,1.829479996,1.512280854
2.45428731,1.990174152,1.534456808
2.987783477,2.78975186,1.725095748
3.651682331,2.966399127,1.972274564
3.768010479,3.211381506,1.993080807
4.509429614,3.642983433,2.541071547
4.81498729,3.888415006,3.218031802

代码如下:

open System.IO
open MathNet.Numerics.LinearAlgebra
let rows = [|for line in File.ReadAllLines("Z:\\mypath.csv") 
            |> Seq.skip 1 do yield line.Split(',') |> Array.map float|]
let data = DenseMatrix.ofRowArrays rows

let data_logdiff = 
    DenseMatrix.init (data.RowCount-1) (data.ColumnCount) 
        (fun j i -> if j = 0 then 0. else data.At(j, i) / data.At(j-1, i) |> log)

let alpha = vector [for i in data_logdiff.EnumerateColumns() -> i |> Statistics.Mean]

let sigsq (values:Vector<float>) (avg: float) =
    let sqr x = x * x
    let result = values |> (fun i -> sqr (i - avg))
    result

sigsq (data_logdiff.Column(i), alpha.[0]) |> printfn "%A"

错误:The type ''a * 'b' is not compatible with the type 'Vector&lt;float&gt;'

这都是针对矩阵和向量之间的广播操作。所有这些杂技都在MATLAB中做一个简单的mean((y-alpha).^2)。

【问题讨论】:

  • 你可以显示 MCVE 吗?
  • matlab 是一种用于矩阵运算的领域特定语言。为什么你会期望一种通用语言能够匹配这种简洁性。顺便说一句,没有什么能阻止你在 F# 中定义 .^。
  • 您能否也添加 mathdotnet 标签,因为其中一些与 mathdotnet 相关,您可能会从熟悉该库的人那里获得更好/更快的帮助。此外,还有.*PointwisePower,所以你可以说data.Column(0) .* data.Column(0)data.Column(0).PointwisePower(2.)
  • @s952163 我经常在 SO 编辑问题的标签,甚至删除多余的标签并将一些转换为更具体的标签。有时我什至使用谷歌搜索 SO 中的问题,然后使用这些结果添加缺少的标签,以便将来仅使用标签更好地找到答案。所以不要羞于编辑标签。

标签: f# math.net mathnet-numerics


【解决方案1】:

您的代码中有错误,F# 编译器会抱怨它,尽管方式有点晦涩难懂。你定义你的函数:

let sigsq (values:Vector<float>) (avg: float) =

这是一个接受两个参数的函数。 (实际上它是一个接受一个参数的函数,返回另一个接受一个参数的函数。)但是你这样称呼它:

sigsq (data_logdiff.Column(i), alpha.[0]) |> printfn "%A"

您对参数进行元组处理,对于 F# 函数,(a,b) 是一个参数,它是一个元组。你应该这样调用你的函数:

sigsq (data_logdiff.Column(0)) (alpha.[0]) 

sigsq <| data_logdiff.Column(0) <| alpha.[0]

还有我最喜欢的:

data_logdiff.Column(0) |> sigsq <| alpha.[0]

我在您的代码中用 0 替换了 (i)。如果你想循环,你可以映射列:

data_logdiff.EnumerateColumnsIndexed() |&gt; Seq.map (fun (i,col) -&gt; sigsq col alpha.[i])

【讨论】:

    猜你喜欢
    • 2015-10-10
    • 2019-04-20
    • 1970-01-01
    • 2017-01-14
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    相关资源
    最近更新 更多