我有一个双值的向量(1D数组),比如X.我需要将这个值向量复制到一个矩阵(2D数组)中,比如Y,这样Y的第一行与X转置相同,第二行与X向左移动一个值相同,Y的第三行与X相同,向左移动两个值,依此类推。
例如,
X = { 1.0, 2.0. 3.0, 4.0, 5.0 }
我需要
Y = 1.0 2.0 3.0 4.0 5.0
2.0 3.0 4.0 5.0 0.0
3.0 4.0 5.0 0.0 0.0
4.0 5.0 0.0 0.0 0.0
5.0 0.0 0.0 0.0 0.0
前段时间,Mathew Finlay发布了将1D数组复制到2D数组以获取值类型的代码。我修改了代码如下:
for (int targetRow = 0; targetRow < N; targetRow++)
{
Buffer.BlockCopy
(
X, // 1D source array
0, // source array offset
Y, // 2D target (destination) array
targetRow * Y.GetLength(targetRow) * sizeof(double), // target array offset
X.Length * sizeof(double) // count
);
}
我不确定这是否能解决问题,更重要的是,这是否是最好的方法。这是更大代码的一部分,这部分需要快速有效,因为向量X和矩阵Y可以变得非常大。
另外,为了使事情复杂化,我可能不需要矢量X的全长(所有值)而只需要它的一部分,因此矩阵Y可以是N×M,其中M <= N.I我不知道如何处理上面的代码。
提前感谢您提供的任何帮助或建议。
编辑: 对于那些感兴趣的人,这里有一些表现结果。
我对这里建议的两种代码(循环和Buffer.BlockCopy)运行了一些速度测试,结果让我感到惊讶。我将Buffer.BlockCopy指定为BC并循环为L.对于10x10矩阵BC = 00:00:00.0000017和L = 00:00:00.0000030。对于100x100矩阵BC = 00:00:00.0000293和L = 00:00:00.0000710。最后,对于1000x1000矩阵BC = 00:00:00.0065340并且L = 00:00:00.0138396。因此,即使对于小矩阵,Buffer.Block副本似乎也优于循环。我在Win 7 Ultimate(64)机器上运行它。
答案 0 :(得分:1)
怎么样?
double[] X = new double[]{ 1.0, 2.0, 3.0, 4.0, 5.0 };
var lbound = X.GetLowerBound(0);
var ubound = X.GetUpperBound(0);
double[,] Y = new double[ubound + 1, ubound + 1];
for (var i = lbound; i <= ubound; i++)
{
for (var j = lbound ; j <= ubound ; j++)
{
Y[i, j] = (i + j) > ubound ? 0.0 : X[i +j];
}
}
修改的
这有效:
for (int targetRow = 0; targetRow <= ubound; targetRow++)
{
Buffer.BlockCopy
(
X, // 1D source array
targetRow * sizeof(double), // source array offset
Y, // 2D target (destination) array
(targetRow * X.Length) * sizeof(double), // target array offset
(X.Length - targetRow) * sizeof(double) // count
);
}
for (var i = 0; i <= ubound; i++)
{
for (var j = 0; j <= ubound; j++)
{
Console.Write(Y[i, j] + " ");
}
Console.WriteLine();
}
Console.ReadKey();
第二次编辑
要处理更改目标数组第二维的其他要求,您需要更改部分BlockCopy
参数targetArrayOffset
和count
,您可以将它们映射到维度目标数组如下所示。
double[] X = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };
var lbound = X.GetLowerBound(0);
var ubound = X.GetUpperBound(0);
double[,] Y = new double[X.Length, 3];
int yLen = Y.GetUpperBound(1) + 1;
for (int targetRow = 0; targetRow <= ubound; targetRow++)
{
Buffer.BlockCopy
(
X, // 1D source array
(targetRow * sizeof(double)), // source array offset
Y, // 2D target (destination) array
((targetRow * yLen) * sizeof(double)),// target array offset
((X.Length - targetRow) > yLen ? yLen : (X.Length - targetRow)) * sizeof(double) // count
);
}
输出:
答案 1 :(得分:0)
假设x
的类型为double[]
,请使用:
var y = new double[x.Length, x.Length];
for (int row = 0; row < x.Length; ++row)
{
for (int col = 0; col < x.Length - row; ++col)
{
y[row, col] = x[col - row];
}
}
或类似。