patterncsharpMinor
Utility method to view submatrices
Viewed 0 times
submatricesutilityviewmethod
Problem
I implemented an utility method that is able to view an
Example:
-- -- -- --
--- --- |1 2| |3 4|
|1 2 3 4| |5 6| |7 8|
|5 6 7 8| => -- --(a0) -- --(a1)
|4 3 2 1| -- -- -- --
|8 7 6 5| |4 3| |2 1|
--- --- |8 7| |6 5|
-- --(a2) -- --(a3)
Nunit test:
Any thoughts about the implementation?
Array[n, m] in another smaller dimension [k, l], where n%k = 0 and m%l = 0. Example:
-- -- -- --
--- --- |1 2| |3 4|
|1 2 3 4| |5 6| |7 8|
|5 6 7 8| => -- --(a0) -- --(a1)
|4 3 2 1| -- -- -- --
|8 7 6 5| |4 3| |2 1|
--- --- |8 7| |6 5|
-- --(a2) -- --(a3)
public static IEnumerable ViewAsNByM(this T[,] values, int n, int m)
{
var count = values.GetLength(0)*values.GetLength(1);
for (int i = 0; i < count/(n*m); ++i)
{
var matrix = new T[n, m];
for (int j = 0; j < n; ++j)
{
for (int k = 0; k < m; ++k)
{
matrix[j, k] = values[j + (i / m * n), (k + i*m)% values.GetLength(0)];
}
}
yield return matrix;
}
}Nunit test:
[Test]
public void TestViewAsNbyM()
{
var numbers = new[,]
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{4, 3, 2, 1},
{8, 7, 6, 5}
};
var aux = numbers.ViewAsNByM(2, 2).ToList();
Assert.AreEqual(4, aux.Count);
var a0 = new[,] {{1, 2}, {5, 6}};
var a1 = new[,] {{3, 4}, {7, 8}};
var a2 = new[,] { { 4, 3 }, { 8, 7 } };
var a3 = new[,] { { 2, 1 }, { 6, 5 } };
Assert.That(aux, Is.EquivalentTo(new[] {a0,a1,a2,a3}));
}Any thoughts about the implementation?
Solution
- Your solution seems to work fine fine for square matrix(where
n = m). However, when presented with non-square matrix, the result becomes purely sporadic. This may or may not be problematic, depending on which kind of matrix you have to deal with.
- Modulo
%is quite expensive.
- You are copying the array item by item. It is not the best way to it, especially when you are copying a continuous section within an array (where
m > 1)
- You should cache the result of
values.GetLength(0), and more importantlyvalues[0].GetLength(0), as they are expensive.
public static IEnumerable ViewAsNByM2(this T[,] values, int n, int m)
{
int height = values.GetLength(0), width = values.GetLength(1);
int rows = height / n, columns = width / m;
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
var matrix = new T[n, m];
for (int i = 0; i < n; i++)
{
Array.ConstrainedCopy(
values, (row * n + i) * width + column * m,
matrix, i * m,
m);
}
yield return matrix;
}
}
}Code Snippets
public static IEnumerable<T[,]> ViewAsNByM2<T>(this T[,] values, int n, int m)
{
int height = values.GetLength(0), width = values.GetLength(1);
int rows = height / n, columns = width / m;
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
var matrix = new T[n, m];
for (int i = 0; i < n; i++)
{
Array.ConstrainedCopy(
values, (row * n + i) * width + column * m,
matrix, i * m,
m);
}
yield return matrix;
}
}
}Context
StackExchange Code Review Q#139204, answer score: 3
Revisions (0)
No revisions yet.