使用 Math.Net 数值与 C# 逐点相乘列数组和矩阵
Point-wise Multiply Column Array and Matrix using Math.Net Numerics with C#
我想使用 Math.Net 数值库对 C# 中给定矩阵中的每一列 array/vector 执行列数组的逐点乘法。
关于此类操作的文档很少,到目前为止我的下面的代码不起作用。我正在尝试使用 LINQ,因为我更喜欢它而不是 for 循环。我在使用 LINQ 时遇到的问题是,当我尝试将矩阵的每一列枚举为向量并执行 PointwiseMultiply() 方法时,我无法重新分配矩阵。
矩阵 fitKernel 是我的矩阵,我想将每一列逐点乘以 wF 列数组并更新我的矩阵fitKernel 使用 LINQ。 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() returns 一个 IEnumerable 向量,但是当我尝试将值分配给 fitKernel 时,它会抱怨将 Enumerable 类型分配给 Matrix。
我想我明白了,但你必须使用 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);
}
如果要写一个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];
}
这可能是最快最简短的解决方案,但我知道它不会告诉 reader 您的想法。 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);
第一行 returns 你的新列,但你仍然必须将它们插入到你的矩阵中。请注意,我们相信枚举器会按自然顺序恢复列。使用 EnumerateColumnsIndexed 可以将其减少到两行。它需要更多细节,但消除了列顺序可能出现的歧义。
顺便说一下,将 PointwiseMultiply 和 SetColumn 组合在一个语句中是行不通的:
var r = c.EnumerateColumnsIndexed().Select((v) => c.SetColumn(v.Item1, v.Item2.PointwiseMultiply(va)));
显然是因为 SetColumn 无效。如果有人有解决方法,请 post 它。
我想使用 Math.Net 数值库对 C# 中给定矩阵中的每一列 array/vector 执行列数组的逐点乘法。
关于此类操作的文档很少,到目前为止我的下面的代码不起作用。我正在尝试使用 LINQ,因为我更喜欢它而不是 for 循环。我在使用 LINQ 时遇到的问题是,当我尝试将矩阵的每一列枚举为向量并执行 PointwiseMultiply() 方法时,我无法重新分配矩阵。
矩阵 fitKernel 是我的矩阵,我想将每一列逐点乘以 wF 列数组并更新我的矩阵fitKernel 使用 LINQ。 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() returns 一个 IEnumerable 向量,但是当我尝试将值分配给 fitKernel 时,它会抱怨将 Enumerable 类型分配给 Matrix。
我想我明白了,但你必须使用 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);
}
如果要写一个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];
}
这可能是最快最简短的解决方案,但我知道它不会告诉 reader 您的想法。 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);
第一行 returns 你的新列,但你仍然必须将它们插入到你的矩阵中。请注意,我们相信枚举器会按自然顺序恢复列。使用 EnumerateColumnsIndexed 可以将其减少到两行。它需要更多细节,但消除了列顺序可能出现的歧义。
顺便说一下,将 PointwiseMultiply 和 SetColumn 组合在一个语句中是行不通的:
var r = c.EnumerateColumnsIndexed().Select((v) => c.SetColumn(v.Item1, v.Item2.PointwiseMultiply(va)));
显然是因为 SetColumn 无效。如果有人有解决方法,请 post 它。