Crop sub-section of 2d Array to a new 2d arry? - c#

int[,] cells = new int[,]
{
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 3, 0, 2, 0, 0},
{0, 0, 0, 4, 6, 0, 0},
{0, 0, 0, 6, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
Hello, i have this 2D array of intergers, i want to crop out the the values to a new 2D array.
What i should end up with is:
1 0 0
3 0 2
0 4 6
0 6 0
What I have is the following, It works if the 2D array is surrounded by 1 row and 1 column. But stops working of the rows and columns increase.
public static int[,] Trim2DArray(int[,] fArray, int n)
{
List<int> rangeX = new List<int>();
List<int> rangeY = new List<int>();
int[,] corrArray = new int[,]{};
if(n == 0)
{
return fArray;
}
else
{
for(int y = 0; y < fArray.GetLength(0); y++)
{
for(int x = 0; x < fArray.GetLength(1); x++)
{
if(fArray[y,x] > 0)
{
rangeX.Add(x);
rangeY.Add(y);
}
}
}
int xm = rangeX.Min();
int ym = rangeY.Min();
int xM = rangeX.Max();
int yM = rangeY.Max();
corrArray = new int[xM,yM];
for(int col = 0; col <= corrArray.GetLength(0)-yM; col++)
{
for(int row = 0; row <= corrArray.GetLength(1)-xM; row++)
{
corrArray[col, row] = fArray[col + xm, row + ym];
}
}
}
return corrArray;
}

You made few mistakes.
Firstly corrArray starts at 0 and ends at xM and yM, so it is too big by xm - 1 and ym - 1 respectively. The -1 is neccessay in case xm==xM or ym==yM - this might happen if only a single row or column has positive numbers. This is the correct way:
corrArray = new int[xM + 1- xm, yM + 1 - ym];
Secondly, you loop indexing wrong.
for (int col = 0; col < corrArray.GetLength(0); col++)
{
for (int row = 0; row < corrArray.GetLength(1); row++)
{
corrArray[col, row] = fArray[col + xm, row + ym];
}
}
You might also consider abandoning list usage, as it's completely unnecessary:
private static int[,] Trim2DArray(int[,] fArray)
{
var startY = -1;
var startX = -1;
var endY = -1;
var endX = -1;
for (int x = 0; x < fArray.GetLength(0); x++)
{
for (int y = 0; y < fArray.GetLength(1); y++)
{
if (fArray[x, y] != 0)
{
if (startX == -1) startX = x;
if (startY == -1) startY = y;
if (x > endX) endX = x;
if (y > endY) endY = y;
}
}
}
if (startX == -1)
{
return new int[0,0];
}
var crop = new int[endX - startX + 1, endY - startY + 1];
for (int x = 0; x < crop.GetLength(0); x++)
{
for (int y = 0; y < crop.GetLength(1); y++)
{
crop[x, y] = fArray[x + startX, y + startY];
}
}
return crop;
}

You have the right idea but you only need to track the four corners rather than building a list of all cells with data.
Here's an example which works for any number of rows and columns.
private static int[,] Trim2DArray(int[,] fArray)
{
var startY = -1;
var startX = -1;
var endY = -1;
var endX = -1;
for (int x = 0; x < fArray.GetLength(0); x++)
{
for (int y = 0; y < fArray.GetLength(1); y++)
{
if (fArray[x, y] != 0)
{
if (startX == -1) startX = x;
if (startY == -1) startY = y;
if (x > endX) endX = x;
if (y > endY) endY = y;
}
}
}
if (startX == -1)
{
return new int[0,0];
}
var crop = new int[endX - startX + 1, endY - startY + 1];
for (int x = 0; x < crop.GetLength(0); x++)
{
for (int y = 0; y < crop.GetLength(1); y++)
{
crop[x, y] = fArray[x + startX, y + startY];
}
}
return crop;
}

Related

Microsoft Solver Foundation gives wrong answer for a simple ILP

I want to solve a binary Linear Problem in C# using Microsoft Solver Foundation. I don't know why I get wrong answer. The Objective Value should be 41.1 but I get 213. The value of 5 variables should be 1 and the other ones should be 0. But I get many many variables with wrong values.
The sum of each row of the matrix should be <= 1. That are my constraints, and as you see in Constraint_arr I get the right constraints.
Thanks for any help.
Define decision variables:
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Decision[,] x = new Decision[name_column.Length, 7];
for (int i = 0; i < name_column.Length; i++)
{
for (int j = 0; j < 7; j++)
{
x[i, j] = new Decision(Domain.IntegerRange(0,1), "x" + i + j);
}
}
for (int i = 0; i < name_column.Length; i++)
{
for (int j = 0; j < 7; j++)
{
model.AddDecisions(x[i, j]);
}
}
Create Constraint and add it to model:
Term[] Constraint_arr = new Term[name_column.Length];
Term tempC;
int jj;
for (int i = 0; i < name_column.Length; i++)
{
tempC = 0;
for (jj= 0; jj < 7; jj++)
{
if(vars_Matrix[i,jj] == 1)
{
tempC += x[i,jj];
}
}
Constraint_arr[i] = tempC;
model.AddConstraints("constraint" + i, Constraint_arr[i] <= 1);
}
Create Objective Function:
Term objective_Func = 0;
Term tempZ;
for (int i = 0; i < name_column.Length; i++)
{
tempZ = 0;
for (int j = 0; j < 7; j++)
{
tempZ += x[i, j] * ratio[i];
}
objective_Func+= tempZ;
}
model.AddGoal("Goal", GoalKind.Maximize, objective_Func);
print the answer:
Solution solution = context.Solve(new SimplexDirective());
Report report = solution.GetReport();
for (int i = 0; i < name_column.Length; i++)
{
for (int j = 0; j < 7; j++)
{
Console.Write(x[i, j]);
}
Console.WriteLine();
}
Console.Write("{0}", report);
Console.ReadLine();
The following MiniZinc model arrives at 14 as maximum value for the objective:
set of int: rows = 1..5;
set of int: cols = 1..7;
array[rows, cols] of 0..1: vars_Matrix = [|0, 0, 1, 0, 1, 1, 1
|0, 0, 1, 1, 0, 1, 1
|0, 0, 1, 0, 0, 0, 0
|0, 0, 1, 1, 0, 1, 1
|0, 0, 0, 0, 1, 0, 0|];
array[cols] of var 0..1: c;
var int: obj;
% constraint
% obj = sum(i in rows)(
% sum(j in cols) (
% c[i] * vars_Matrix[i, j]
% )
% );
constraint
obj = sum([ sum([ c[i] * vars_Matrix[i, j] | j in cols ]) | i in rows ]);
solve maximize(obj);
Output
c = array1d(1..7, [1, 1, 1, 1, 1, 1, 1]);
obj = 14;
The same result is obtained from the following Z3py model:
from z3 import *
s = Optimize()
Rows = range(5);
Cols = range(7);
vars_Matrix = [[0, 0, 1, 0, 1, 1, 1],
[0, 0, 1, 1, 0, 1, 1],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 1],
[0, 0, 0, 0, 1, 0, 0]]
c = [Int("c" + str(i+1)) for i in Rows]
obj = Int("obj")
for i in Rows:
s.add(c[i] >= 0, c[i] <= 1)
s.add(obj == Sum( [ Sum( [ c[i] * vars_Matrix[i][j] for j in Cols ] ) for i in Rows ] ))
s.maximize(obj)
if sat == s.check():
print(s.model())
else:
print("No solution. Sorry!")

Understanding Marching Square algorithm

The following picture is retrieved from Wikipedia:
I haven't understood this part:
I have two questions here:
Where did they obtain [8,4,1,2] from and what did they want to tell us by that?
Take a look at cell [0, 0] whose value is 13. If I go clockwise along with its contouring values, I obtain the binary string 0010 which is 2. How does the 1st cell-value become 13?
.
enum What
{
lines, surface, both
}
class Program
{
public static void Print(int[,] data, int xn, int yn)
{
for (int j = 0; j < yn; j++)
{
for (int i = 0; i < xn; i++)
{
Console.Write(data[i,j] + ", ");
}
Console.WriteLine();
}
}
public static int[,] normalize(int[,] data, int xn, int yn)
{
for (int j = 0; j < yn; j++)
{
for (int i = 0; i < xn; i++)
{
if (data[i, j] > 1)
{
data[i, j] = 0;
}
else
{
data[i, j] = 1;
}
}
}
return data;
}
public static int[,] marching_square(int x, int y, int[,] data, int isovalue, What what)
{
int xn = x;
int yn = y;
data = normalize(data, xn, yn);
int[,] bitMask = new int[xn - 1, yn - 1];
for (int j = 0; j < yn - 1; j++)
{
for (int i = 0; i < xn - 1; i++)
{
StringBuilder sb = new StringBuilder();
sb.Append(data[i, j]);
sb.Append(data[i, j + 1]);
sb.Append(data[i + 1, j]);
sb.Append(data[i + 1, j + 1]);
bitMask[i, j] = Convert.ToInt32(sb.ToString(), 2);
}
}
return bitMask;
}
static void Main(string[] args)
{
int[,] data = new int[,] {
{ 1,1,1,1,1 },
{ 1,2,3,2,1 },
{ 1,3,3,3,1 },
{ 1,2,3,2,1 },
{ 1,1,1,1,1 }
};
Print(data, 5,5);
int[,] bitMask = marching_square(5,5,data, 0, What.lines);
Print(bitMask, 4, 4);
}
}
Output:
1, 1, 1, 1, 1,
1, 2, 3, 2, 1,
1, 3, 3, 3, 1,
1, 2, 3, 2, 1,
1, 1, 1, 1, 1,
14, 10, 10, 11,
12, 0, 0, 3,
12, 0, 0, 3,
13, 5, 5, 7,
I inverted the bits. But, the output looks different.

why is my c# code so slow [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Tihs is a code that impliments the adaptive histogram equalization algorithm,called by a button in the c# main form, the image is about 1024*768 in size. The problem is this code is too slow ,I don't know where I should modify to improve the performance...Please give me some advice....thanks..
private void AHE_BMP_advanced(Int32 halfblocksize)
{
//adaptive histogram equalization
Size imgsz = sourceBMP.Size;
//compute total number of pixels
double totalNum = imgsz.Height * imgsz.Width;
//temp image for storation
Bitmap tempImg = new Bitmap(imgsz.Width, imgsz.Height);
//region statistics
double[,] prob = new double[256, 3];
Int32[,] mapping = new Int32[256, 3];
double[] probSum = new double[3];
for (int i = 0; i < imgsz.Height; i++)
{
for (int j = 0; j < imgsz.Width; j++)
{
//this.textBox2.Text = "i=" + i.ToString() + "j=" + j.ToString();
for (int u = 0; u < 256; u++) {
for (int v = 0; v < 3; v++) {
prob[u, v] = 0;
mapping[u, v] = 0;
}
}
//produce ahe for this pixel:
for (int u = i - halfblocksize; u <= i + halfblocksize; u++)
{
for (int v = j - halfblocksize; v <= j + halfblocksize; v++)
{
//uv->hi,wi;
int hi, wi;
hi = u;
wi = v;
//mirror:
if (hi < 0) hi = -hi;
else if (hi >= imgsz.Height)
hi = 2 * (imgsz.Height - 1) - hi;
if (wi < 0) wi = -wi;
else if (wi >= imgsz.Width)
wi = 2 * (imgsz.Width - 1) - wi;
//get hist
prob[sBmpdata[wi,hi,0], 0] += 1;
prob[sBmpdata[wi,hi,1], 1] += 1;
prob[sBmpdata[wi,hi,2], 2] += 1;
}
}
//get ahe value:
//probSum init:
probSum[0] = 0;
probSum[1] = 0;
probSum[2] = 0;
for (int k = 0; k < 256; k++)
{
this.textBox2.Text += "prob[" + k.ToString()+ ",0]=" +
prob[k,0].ToString()+"\r\n";
prob[k, 0] /= totalNum;
prob[k, 1] /= totalNum;
prob[k, 2] /= totalNum;
//Sum
probSum[0] += prob[k, 0];
probSum[1] += prob[k, 1];
probSum[2] += prob[k, 2];
if(i==40&&j==40)
//mapping(INT32)
mapping[k, 0] = Convert.ToInt32(255.0 * probSum[0]);
mapping[k, 1] = Convert.ToInt32(255.0 * probSum[1]);
mapping[k, 2] = Convert.ToInt32(255.0 * probSum[2]);
}
tempImg.SetPixel(j, i,
Color.FromArgb(mapping[sBmpdata[j,i,0], 0],
mapping[sBmpdata[j,i,1], 1], mapping[sBmpdata[j,i,2], 2]));
}
}
this.pictureBox1.Image = tempImg;
}
SetPixel
SetPixel is very slow. Look in to using LockBits. MSDN has good example.
String concatenation inside a loop
This line inside a loop is also inefficient as it creates 256 strings for each pixel, so 201 million strings allocated, that's got to be expensive!
for (int k = 0; k < 256; k++)
this.textBox2.Text += "prob[" + k.ToString()+ ",0]=" + prob[k,0].ToString()+"\r\n";
If it's debug, take it out, 201 million lines of debug text is not useful to you. It you need it you are better off writing to a file as otherwise it's going to take many GB's of ram to store the final string.
Using SetPixel is actually a fairly inefficient way of working with image data. If you want to scan across the whole image I'd suggest manipulating the image data directly using the BitmapData class.
// Create a new bitmap.
Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
// Set every third value to 255. A 24bpp bitmap will look red.
for (int counter = 2; counter < rgbValues.Length; counter += 3)
rgbValues[counter] = 255;
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
// Draw the modified image.
e.Graphics.DrawImage(bmp, 0, 150);
Well, I think you should write
private void AHE_BMP_advanced(Int32 halfblocksize)
{
this.pictureBox1.Image = GetAHE_BMP_advanced(halfblocksize, sourceBMP.Size, sBmpdata);
}
where GetAHE_BMP_advanced is
private static Bitmap GetAHE_BMP_advanced(int halfblocksize, Size sourceBmpSize, int[,,] sourceBmpData)
{
const int m = 256;
const int n = 3;
//adaptive histogram equalization
Size imgsz = sourceBmpSize;
//compute total number of pixels
double totalNum = imgsz.Height * imgsz.Width;
var colors = new Color[sourceBmpSize.Width, sourceBmpSize.Height];
for (int i = 0; i < imgsz.Height; i++)
{
for (int j = 0; j < imgsz.Width; j++)
{
double[,] prob = new double[m, n];
int[,] mapping = new int[m, n];
//produce ahe for this pixel:
for (int u = i - halfblocksize; u <= i + halfblocksize; u++)
{
for (int v = j - halfblocksize; v <= j + halfblocksize; v++)
{
int hi = u;
int wi = v;
//mirror:
if (hi < 0) hi = -hi;
else if (hi >= imgsz.Height)
hi = 2 * (imgsz.Height - 1) - hi;
if (wi < 0) wi = -wi;
else if (wi >= imgsz.Width)
wi = 2 * (imgsz.Width - 1) - wi;
//get hist
prob[sourceBmpData[wi, hi, 0], 0] += 1;
prob[sourceBmpData[wi, hi, 1], 1] += 1;
prob[sourceBmpData[wi, hi, 2], 2] += 1;
}
}
double[] probSum = new double[n];
for (int k = 0; k < m; k++)
{
prob[k, 0] /= totalNum;
prob[k, 1] /= totalNum;
prob[k, 2] /= totalNum;
//Sum
probSum[0] += prob[k, 0];
probSum[1] += prob[k, 1];
probSum[2] += prob[k, 2];
if (i == 40 && j == 40) //mapping(INT32)
{
mapping[k, 0] = Convert.ToInt32(255.0 * probSum[0]);
mapping[k, 1] = Convert.ToInt32(255.0 * probSum[1]);
mapping[k, 2] = Convert.ToInt32(255.0 * probSum[2]);
}
}
colors[i, j] = Color.FromArgb(mapping[sourceBmpData[j, i, 0], 0],
mapping[sourceBmpData[j, i, 1], 1],
mapping[sourceBmpData[j, i, 2], 2]);
}
}
return BitmapHelper.CreateBitmap(colors);
}
where BitmapHelper is:
public static class BitmapHelper
{
public struct Pixel : IEquatable
{
// ReSharper disable UnassignedField.Compiler
public byte Blue;
public byte Green;
public byte Red;
public bool Equals(Pixel other)
{
return Red == other.Red && Green == other.Green && Blue == other.Blue;
}
}
public static Color[,] GetPixels(Bitmap two)
{
return ProcessBitmap(two, pixel => Color.FromArgb(pixel.Red, pixel.Green, pixel.Blue));
}
public static float[,] GetBrightness(Bitmap two)
{
return ProcessBitmap(two, pixel => Color.FromArgb(pixel.Red, pixel.Green, pixel.Blue).GetBrightness());
}
public static unsafe T[,] ProcessBitmap<T>(Bitmap bitmap, Func<Pixel, T> func)
{
var lockBits = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
bitmap.PixelFormat);
int padding = lockBits.Stride - (bitmap.Width * sizeof(Pixel));
int width = bitmap.Width;
int height = bitmap.Height;
var result = new T[height, width];
var ptr = (byte*)lockBits.Scan0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
var pixel = (Pixel*)ptr;
result[i, j] = func(*pixel);
ptr += sizeof(Pixel);
}
ptr += padding;
}
bitmap.UnlockBits(lockBits);
return result;
}
public static Bitmap CreateBitmap(Color[,] colors)
{
const int bytesPerPixel = 4, stride = 8;
int width = colors.GetLength(0);
int height = colors.GetLength(1);
byte[] bytes = new byte[width*height*bytesPerPixel];
int n = 0;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
bytes[n++] = colors[i, j].R;
bytes[n++] = colors[i, j].G;
bytes[n++] = colors[i, j].B;
bytes[n++] = colors[i, j].A;
}
}
return CreateBitmap(bytes, width, height, stride, PixelFormat.Format32bppArgb);
}
public static Bitmap CreateBitmap(byte[] data, int width, int height, int stride, PixelFormat format)
{
var arrayHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
var bmp = new Bitmap(width, height, stride, format, arrayHandle.AddrOfPinnedObject());
arrayHandle.Free();
return bmp;
}
}

index outside bounds of the array adaptive median

I'm trying to output a new image after applying the adaptive median filter but it only works if the maximum window size is 3*3, but it should work for all odd window sizes, and it does so if the image is so small for example 10*10 pixels, but if the image is for example 440*445 pixels it only works if the max window size is 3*3 otherwise it says index outside bounds of the array, here is my code using counting sort to sort the pixels:
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace ImageFilters
{
public class Class2
{
public byte[,] median(byte[,] array, int width, int height, int msize)
{
byte[,] marr = new byte[height + 1, width + 1];
int size = 3;
for (int i = 0; i <height+1; i++)
{
marr[i, 0] = 255;
}
for (int j = 0; j < width+1; j++)
{
marr[0, j] = 255;
}
int n=0;
int z=0;
for (int k = 0; k < (height) * width; k++)
{
repeat:
byte[] farr = new byte[size * size];
int I=0;
for (int i = n; i < n+size; i++)
{
for (int j = z; j < z+size; j++)
{
if (j < width && i < height)
{
farr[I] = array[i, j];
I++;
}
else
{
farr[I] = 0;
I++;
}
}
}
int zxy = farr[(size*size)/2];
byte[] check = new byte[size * size];
check=counting(farr,size);
int median = 0;
int lennn;
lennn = check.Length;
int min = 99999;
int maxi = -1;
int a1, a2;
min = check.Min();
maxi = check.Max();
median = check[lennn / 2];
a1 = median - min;
a2 = maxi - median;
int b1, b2;
b1 = zxy - min;
b2 = maxi - zxy;
if (a1 > 0 && a2 > 0)
{
if (b1 > 0 && b2 > 0)
{
marr[n + 1, z + 1] = Convert.ToByte(zxy);
z++;
if (z + (size - 1) > (width + 1))
{
n++;
z = 0;
}
}
else
{
marr[n + 1, z + 1] = Convert.ToByte(median);
z++;
if (z + (size - 1) > (width + 1))
{
n++;
z = 0;
}
}
}
else
{
size = size + 2;
if (size <= msize)
goto repeat;
else
{
marr[n +1, z +1] = Convert.ToByte(median);
z++;
if (size > 3)
size = 3;
if (z + (size - 1) > (width + 1))
{
n++;
z = 0;
}
}
}
}
return marr;
}
public static byte[] counting(byte[] array1D, int siz)
{
int max = -10000000;
byte[] SortedArray = new byte[siz * siz];
max = array1D.Max();
byte[] Array2 = new byte[max + 1];
//for (int i = 0; i < Array2.Length; i++)
// Array2[i] = 0; // create new array ( Array2) with zeros in every index .
for (int i = 0; i < (siz*siz); i++)
{
Array2[array1D[i]] += 1; //take the element in the index(i) of(array1d) AS the index of (Array2)
// and increment the element in this index by 1 .
}
for (int i = 1; i <= max; i++)
{
Array2[i] += Array2[i - 1]; // Count every element in (array1d) and put it in (Array2).
}
for (int i = (siz*siz) - 1; i >= 0; i--)
{
SortedArray[Array2[array1D[i]] - 1] = array1D[i]; // transfer the element in index (i) of (array1d) to (SortedArray
Array2[array1D[i]]--;
}
return SortedArray;
}
}
}
Any help will be appreciated, thank you.

Smallest and biggest value in slice of 3D array

I have a 3d-array double[,,] numbers = new double[x,y,z]; and now if one imagines the 3d-array to look like a cube with numbers I need to find the smallest and biggest value of every slice along all three directions.
It is of course easy to do by simply looping over it, but does C# have any functions to find the smallest and biggest value in a slice?
To explain it a bit further, maybe this "unreal" code will help:
int i;
double[] xmin = new double[x];
double[] xmax = new double[x];
double[] ymin = new double[y];
double[] ymax = new double[y];
double[] zmin = new double[z];
double[] zmax = new double[z];
for(i = 0; i < x; i++)
{
MinOf(numbers[i, y, z]) = xmin[i];
MaxOf(numbers[i, y, z]) = xmax[i];
}
for(i = 0; i < y; i++)
{
MinOf(numbers[x, i, z]) = ymin[i];
MaxOf(numbers[x, i, z]) = ymax[i];
}
for(i = 0; i < z; i++)
{
MinOf(numbers[x, y, i]) = zmin[i];
MaxOf(numbers[x, y, i]) = zmax[i];
}
Hopefully someone can help me with that.
Cheers, Phil13131
You can make methods for enumerating the slices. This is for one dimension, you would need another two, but I think you can manage that:
public static IEnumerable<T> SliceX<T>(T[,,] data, int x) {
for (int y = 0; y < data.GetLength(1); y++) {
for (int z = 0; z < data.GetLength(2); z++) {
yield return data[x, y, z];
}
}
}
Then you can just use the Min and Max methods, but that will of course loop through the data twice:
double min = SliceX(numbers, x).Min();
double max = SliceX(numbers, x).Max();
You can make an extension method that gets both min and max in one iteration:
public static class IEnumerableExtensions {
public static void GetMinMax<T>(this IEnumerable<T> data, out T min, out T max) where T : IComparable<T> {
bool first = true;
min = max = default(T);
foreach (T value in data) {
if (first) {
min = max = value;
first = false;
} else {
if (value.CompareTo(min) < 0) min = value;
if (value.CompareTo(max) > 0) max = value;
}
}
}
}
Usage:
double min, max;
SliceX(numbers, 0).GetMinMax(out min, out max);
Are you looking for something like this?
double[, ,] numbers = new double[2, 2, 2];
numbers[0, 0, 0] = 0;
numbers[0, 0, 1] = 1;
numbers[0, 1, 0] = 2;
numbers[0, 1, 1] = 3;
numbers[1, 0, 0] = 4;
numbers[1, 0, 1] = 5;
numbers[1, 1, 0] = 6;
numbers[1, 1, 1] = 7;
double[] xmax = new double[numbers.GetLength(0)];
double[] ymax = new double[numbers.GetLength(1)];
double[] zmax = new double[numbers.GetLength(2)];
for (int x = 0; x < xmax.Length; x++) xmax[x] = int.MinValue;
for (int y = 0; y < ymax.Length; y++) ymax[y] = int.MinValue;
for (int z = 0; z < zmax.Length; z++) zmax[z] = int.MinValue;
for (int x = 0; x < xmax.Length; x++)
for (int y = 0; y < ymax.Length; y++)
for (int z = 0; z < zmax.Length; z++)
{
xmax[x] = Math.Max(xmax[x], numbers[x, y, z]);
ymax[y] = Math.Max(ymax[y], numbers[x, y, z]);
zmax[z] = Math.Max(zmax[z], numbers[x, y, z]);
}
// xmax == { 3, 7 }
// ymax == { 5, 7 }
// zmax == { 6, 7 }

Categories

Resources