0

我想使用 Math.Net Numerics 库在 C# 中的给定矩阵中执行列数组与每个列数组/向量的逐点乘法。

关于这样的操作的文档很少,到目前为止,我有下面的代码不起作用。我正在尝试使用 LINQ,因为我更喜欢 for 循环。我在使用 LINQ 时遇到的问题是,当我尝试将矩阵的每一列枚举为向量并执行 PointwiseMultiply() 方法时,我无法重新分配矩阵。

矩阵fitKernel是我的矩阵,我想将每列逐点乘以wF列数组并使用 LINQ更新我的矩阵fitKernel 。fitKernel 是 9 x 5 矩阵,而 wF 是一个 9 x 1 double[] 数组,我在下面的 LINQ 中将其转换为 Vector。

Matrix<double> fitKernel = Matrix<double>.Build.DenseOfColumnArrays(c1, c2, c3, c4, ones); 

double[] wF = Enumerable.Repeat(1.0, 9).ToArray();

fitKernel = fitKernel.EnumerateColumns()
            .Select(v => v.PointwiseMultiply(Vector<double>.Build.DenseOfArray(wF)));

上面使用 EnumerateColumns() 的代码返回向量的 IEnumerable,但是当我尝试将值分配给 fitKernel 时,它抱怨将 Enumerable 类型分配给矩阵。

4

3 回答 3

1

如果你要写一个 for 循环,你不妨写两个。

    // a = double[9];
    // c = Matrix<double>

    for (int ic = 0; ic < c.ColumnCount; ic++)
    {
        for (int ir = 0; ir < c.RowCount; ir++) c[ir, ic] = a[ir] * c[ir, ic];
    }

这可能是最快和最简短的解决方案,但我知道它并没有告诉读者您的想法。OTOH,如果你要使用枚举器,让它控制循环是有意义的。

        var va = Vector<double>.Build.DenseOfArray(a);

        var ColEnum = c.EnumerateColumnsIndexed() ;

        foreach (System.Tuple<int,Vector<double>> col in ColEnum)
        {
            Vector<double> v = (Vector<double>)col.Item2.PointwiseMultiply((Vector<double>)va);
            c.SetColumn(col.Item1, v);
        } 

我能得到的最接近你的第一个公式的是:

        var r = c.EnumerateColumns().Select(v => v.PointwiseMultiply(va));
        int i = 0;
        foreach (Vector ri in r) c.SetColumn(i++, ri);

第一行返回您的新列,但您仍然必须将它们插入到您的矩阵中。请注意,我们信任枚举器以自然顺序恢复列。可以使用 EnumerateColumnsIndexed 将其减少到两行。它需要更多细节,但消除了关于列顺序的可能歧义。

于 2018-07-02T15:09:47.113 回答
1

顺便说一句,将 PointwiseMultiply 和 SetColumn 组合在一个语句中是行不通的,如下所示:

        var r = c.EnumerateColumnsIndexed().Select((v) => c.SetColumn(v.Item1, v.Item2.PointwiseMultiply(va)));

显然是因为 SetColumn 是无效的。如果有人有解决方法,请发布。

于 2018-07-04T14:15:28.053 回答
0

我想我明白了,但你必须使用 for 循环;使用 LINQ 似乎不是什么简单的方法:

for (int i = 0; i < fitKernel.ColumnCount; i++)
{
        var v = fitKernel.Column(i);
        v = v.PointwiseMultiply(Vector<double>.Build.DenseOfArray(wF));
        fitKernel.SetColumn(i, v);
}
于 2018-06-22T15:19:26.820 回答