I have a linear array which I need to reshape as of a stack of 2D data. In this particular case, the stack only contains one element so the output should be an array with dimensions (height, width, 1).
This is related to a previous question , where I was asking about the same operation in the other direction (3D to 1D).
What is the fastest way to map this data to a 3D array?
I was planning to take the following approach:
public static byte[, ,] ToBuffer3D<TDepth>(this byte[] buffer, int w, int h)
{
byte[, ,] buff3D = new byte[h, w, 1];
for (int i = 0; i < buffer.Length; i++)
{
buff3D[(int)Math.Floor(i / (double)w), i % w, 0] = buffer[i];
}
return buff3D;
}
But it seems like it might be possible to take advantage of how the data is already stored in memory to copy more than one element at a time. Is there some other mapping approach that could be employed in C#?
This is likely to be somewhat faster:
public static byte[,,] ToBuffer3Da(this byte[] buffer, int w, int h)
{
byte[,,] buff3D = new byte[h, w, 1];
Buffer.BlockCopy(buffer, 0, buff3D, 0, h*w);
return buff3D;
}
if you use the base class and implementation defined below, you have a class that supports both linear and dimensional indexing at the same time. No conversion or copying is necessary.
Use it like this,
var matrix = new DecomposedMatrix<byte>(10, 10, 10)
foreach(var b int matrix)
{
...
}
for (var i = 0; i < matrix.Count; i++)
{
...
var item = matrix[i];
...
}
for (var x = 0; x < matrix.H; x++)
for (var y = 0; y < matrix.W; y++)
for (var z = 0; z < matrix.D; z++)
{
...
var item = matrix[x, y, z];
...
}
classes follow ...
public abstract class DecomposedMatrix
{
private readonly int h;
private readonly int w;
private readonly int d;
protected DecomposedMatrix(int h, int w, int d)
{
this.h = h;
this.w = w;
this.d = d;
}
public int W
{
get
{
return this.w;
}
}
public int D
{
get
{
return this.d;
}
}
public int H
{
get
{
return this.h;
}
}
protected int DereferenceCoordinates(int x, int y, int z)
{
if (x >= this.H || y >= this.W || z >= this.D)
{
throw new IndexOutOfRangeException();
}
if (x < 0 || y < 0 || z < 0)
{
throw new IndexOutOfRangeException();
}
return z + (y * this.D) + (x * this.W * this.D);
}
}
and the implementation
public class DecomposedMatrix<T> : DecomposedMatrix, IReadOnlyList<T>
{
private readonly IList<T> data;
public DecomposedMatrix(int h, int w, int d)
: base(h, w, d)
{
this.data = new T[h * w * d];
}
public T this[int index]
{
get
{
return this.data[index];
}
set
{
this.data[index] = value;
}
}
public T this[int x, int y, int z]
{
get
{
return this.data[this.DereferenceCoordinates(x, y, z)];
}
set
{
this.data[this.DereferenceCoordinates(x, y, z)] = value;
}
}
public int Count
{
get
{
return this.data.Count;
}
}
public IEnumerator<T> GetEnumerator()
{
return this.data.GetEnumerator();
}
public IEnumerator IEnumerable.GetEnumerator()
{
return this.data.GetEnumerator();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.