The total and comprehensive solution is fairly simple. You need to create a wrapper class with the following interface:
class IArrayWrapper {
ushort SmallSquareSize { get; set; }
int CurrentDimension { get; }
double this[int xIndex, int yIndex] { get; }
}
class ArrayWrapper : IArrayWrapper {
internal ArrayWrapper(uint baseDimension) {
Implementation = new double[baseDimension, baseDimension];
}
ushort IArrayWrapper.SmallSquareSize {
get { return fSmallSquareSize; }
set {
if (fSmallSquareSize == value) return;
fSmallSquareSize = value;
}
}
int IArrayWrapper.CurrentDimension { get { } }
double IArrayWrapper.this[int xIndex, int yIndex] { get { } }
double[,] Implementation;
ushort fSmallSquareSize = 1;
}
I introduced the interface only for simplicity of explanation and because implementation is incomplete. You can easily complete it; and you can get rid of interface, implement it all as just regular class members. According to your question, I leave it to you.
Are you getting the picture? I've done your
Implementation
array dimensions depending on your constructor call. The
SmallSquareSize
property defines the virtual dimension. For example, if the
Implementation
is 27x27, and
SmallSquareSize
is 3, virtual dimension is 9x9 and you have to average data by the squared 3x3. So, I've added some flexibility to your data model.
Please decide by yourself if you get non-integer number of small squares when, for example, you cannot divide 256 by 3 without remainder. This is not a big problem as you can ignore remaining areas and provide data only for averages part of the big square. Alternatively, you could throw exception if the base dimension cannot be divided by the dimension of a small square without remainder, but I would rather avoid it.
—SA