public void NestedView_2D() { var data = new ArraySlice <int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }).Reshape(2, 10); //>>> x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) //>>> x = x.reshape(2, 10) //>>> x //array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]) // return identical view var identical = new ArraySlice <int>(data, ":"); Assert.AreEqual(new Shape(2, 10), identical.Shape); //>>> x[:, 1:9] //array([[1, 2, 3, 4, 5, 6, 7, 8], // [1, 2, 3, 4, 5, 6, 7, 8]]) var view1 = new ArraySlice <int>(identical, ":,1:9"); Assert.AreEqual(new Shape(2, 8), view1.Shape); Assert.AreEqual(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }, view1); //>>> x[:, 1:9][:,::- 2] //array([[8, 6, 4, 2], // [8, 6, 4, 2]]) var view2 = new ArraySlice <int>(view1, ":,::-2"); Assert.AreEqual(new Shape(2, 4), view2.Shape); Assert.AreEqual(new int[] { 8, 6, 4, 2, 8, 6, 4, 2 }, view2); //>>> x[:, 1:9][:,::- 2][:,::- 3] //array([[2, 8], // [2, 8]]) var view3 = new ArraySlice <int>(view2, ":,::-3"); Assert.AreEqual(new Shape(2, 2), view3.Shape); Assert.AreEqual(new int[] { 2, 8, 2, 8 }, view3); // all must see the same modifications, no matter if original or any view is modified // modify original data.SetValues(0, new int[] { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }); Assert.AreEqual(new int[] { -1, -2, -3, -4, -5, -6, -7, -8, -1, -2, -3, -4, -5, -6, -7, -8 }, view1); Assert.AreEqual(new int[] { -8, -6, -4, -2, -8, -6, -4, -2 }, view2); Assert.AreEqual(new int[] { -2, -8, -2, -8 }, view3); // modify views view1[0, 7] = 88; view1[1, 7] = 888; Assert.AreEqual(new int[] { 0, -1, -2, -3, -4, -5, -6, -7, 88, -9, 0, -1, -2, -3, -4, -5, -6, -7, 888, -9 }, data); Assert.AreEqual(new int[] { -1, -2, -3, -4, -5, -6, -7, 88, -1, -2, -3, -4, -5, -6, -7, 888 }, view1); Assert.AreEqual(new int[] { 88, -6, -4, -2, 888, -6, -4, -2 }, view2); Assert.AreEqual(new int[] { -2, 88, -2, 888 }, view3); view3[0, 0] = 22; view3[1, 0] = 222; Assert.AreEqual(new int[] { 0, -1, 22, -3, -4, -5, -6, -7, 88, -9, 0, -1, 222, -3, -4, -5, -6, -7, 888, -9 }, data); Assert.AreEqual(new int[] { -1, 22, -3, -4, -5, -6, -7, 88, -1, 222, -3, -4, -5, -6, -7, 888 }, view1); Assert.AreEqual(new int[] { 88, -6, -4, 22, 888, -6, -4, 222 }, view2); Assert.AreEqual(new int[] { 22, 88, 222, 888 }, view3); }
public void NestedView_1D() { var data = new ArraySlice <int>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // return identical view var identical = new ArraySlice <int>(data, ":"); Assert.AreEqual(new Shape(10), identical.Shape); var view1 = new ArraySlice <int>(identical, "1:9"); Assert.AreEqual(new Shape(8), view1.Shape); Assert.AreEqual(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, }, view1); var view2 = new ArraySlice <int>(view1, "::-2"); Assert.AreEqual(new Shape(4), view2.Shape); Assert.AreEqual(new int[] { 8, 6, 4, 2, }, view2); var view3 = new ArraySlice <int>(view2, "::-3"); Assert.AreEqual(new Shape(2), view3.Shape); Assert.AreEqual(new int[] { 2, 8 }, view3); // all must see the same modifications, no matter if original or any view is modified // modify original data.SetValues( 0, new int[] { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }); Assert.AreEqual(new int[] { -1, -2, -3, -4, -5, -6, -7, -8, }, view1); Assert.AreEqual(new int[] { -8, -6, -4, -2, }, view2); Assert.AreEqual(new int[] { -2, -8 }, view3); // modify views view1[7] = 88; Assert.AreEqual(new int[] { 0, -1, -2, -3, -4, -5, -6, -7, 88, -9 }, data); Assert.AreEqual(new int[] { -1, -2, -3, -4, -5, -6, -7, 88, }, view1); Assert.AreEqual(new int[] { 88, -6, -4, -2, }, view2); Assert.AreEqual(new int[] { -2, 88 }, view3); view3[0] = 22; Assert.AreEqual(new int[] { 0, -1, 22, -3, -4, -5, -6, -7, 88, -9 }, data); Assert.AreEqual(new int[] { -1, 22, -3, -4, -5, -6, -7, 88, }, view1); Assert.AreEqual(new int[] { 88, -6, -4, 22, }, view2); Assert.AreEqual(new int[] { 22, 88 }, view3); }
public void ImageProcessingExample() { var width = 4; // px var height = 4; // px var bytes_per_pixel = 3; // r, g, b // note that Slice and Dice uses the row major coordinate system like numpy // so the coordinate order is y, x, color in this example var shape = new Shape(height, width, bytes_per_pixel); // create the raw pixel data using Shape.Size to calculate how long the array // must be to hold a 3D volume of h x w x byte_per_pixel var raw_bytes = new byte[shape.Size]; var image = new ArraySlice <byte>(raw_bytes, shape); // we can now access single pixel values by coordinates // get the three bytes for the pixel at the upper right corner // as ArraySlice<T> without copying any data! var pixel = image.GetSlice("0, 3"); Console.WriteLine("pixel: " + pixel); // prints: pixel: [0, 0, 0] // set the pixel to white image.SetValues(new int[] { 0, 3 }, new byte[] { 255, 255, 255 }); // get the 2 by 2 pixel patch at the center and color it green without copying any data: var patch = image.GetSlice("1:3, 1:3, 1"); // this gets only the green channel // note how we can now use relative coordinates in the patch // since this is a slice of the green channel we can directly set the green byte at location (y,x) for (int y = 0; y < 2; y++) { for (int x = 0; x < 2; x++) { patch[y, x] = 255; } } // print the bitmap out row by row like this (black = '#', white = ' ', green= 'o') // obviously by using slicing this is a no-brainer for (int y = 0; y < height; y++) { Console.Write("|"); // Slice.Index gives us a slice-definition for a row at index y. // You could also use image.GetSlice($"{y}") var row = image.GetSlice(Slice.Index(y)); for (int x = 0; x < width; x++) { var red = row[x, 0]; var green = row[x, 1]; if (red == 0 && green == 0) { // must be black Console.Write("#"); continue; } if (red == 255 && green == 255) { // must be white Console.Write(" "); continue; } if (green == 255) { Console.Write("o"); } } // at the end of the row, break the line Console.WriteLine("|"); } }