From 60003ca3f2bf9a306c68b967b8167a601d62fa28 Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 10:09:01 +0100 Subject: [PATCH 1/7] Redesign : amin, amax now work for NDArray --- src/NumSharp.Core/Extensions/NdArray.AMin.cs | 70 ---------------- src/NumSharp.Core/Extensions/NumPy.min.cs | 15 ---- src/NumSharp.Core/Math/NumPy.amax.cs | 58 +------------ src/NumSharp.Core/Math/NumPy.amin.cs | 66 +-------------- src/NumSharp.Core/NumPyGeneric.cs | 15 +--- .../{Extensions => Selection}/NdArray.AMax.cs | 54 ++++++------ src/NumSharp.Core/Selection/NdArray.AMin.cs | 84 +++++++++++++++++++ .../NDArray.AMax.Test.cs | 18 ++-- .../NDArray.AMin.Test.cs | 16 ++-- 9 files changed, 134 insertions(+), 262 deletions(-) delete mode 100644 src/NumSharp.Core/Extensions/NdArray.AMin.cs delete mode 100644 src/NumSharp.Core/Extensions/NumPy.min.cs rename src/NumSharp.Core/{Extensions => Selection}/NdArray.AMax.cs (52%) create mode 100644 src/NumSharp.Core/Selection/NdArray.AMin.cs rename test/NumSharp.UnitTest/{Extensions => Selection}/NDArray.AMax.Test.cs (75%) rename test/NumSharp.UnitTest/{Extensions => Selection}/NDArray.AMin.Test.cs (86%) diff --git a/src/NumSharp.Core/Extensions/NdArray.AMin.cs b/src/NumSharp.Core/Extensions/NdArray.AMin.cs deleted file mode 100644 index b6850b4b9..000000000 --- a/src/NumSharp.Core/Extensions/NdArray.AMin.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NumSharp.Core.Extensions -{ - public static partial class NDArrayExtensions - { - public static NDArrayGeneric AMin(this NDArrayGeneric np, int? axis = null) - { - NDArrayGeneric res = new NDArrayGeneric(); - if (axis == null) - { - res.Data = new double[1] { np.Data.Min() }; - res.Shape = new Shape(new int[] { 1 }); - } - else - { - if (axis < 0 || axis >= np.NDim) - throw new Exception("Invalid input: axis"); - int[] resShapes = new int[np.Shape.Shapes.Count - 1]; - int index = 0; //index for result shape set - //axis departs the shape into three parts: prev, cur and post. They are all product of shapes - int prev = 1; - int cur = 1; - int post = 1; - int size = 1; //total number of the elements for result - //Calculate new Shape - for (int i = 0; i < np.Shape.Shapes.Count; i++) - { - if (i == axis) - cur = np.Shape.Shapes[i]; - else - { - resShapes[index++] = np.Shape.Shapes[i]; - size *= np.Shape.Shapes[i]; - if (i < axis) - prev *= np.Shape.Shapes[i]; - else - post *= np.Shape.Shapes[i]; - } - } - res.Shape = new Shape(resShapes); - //Fill in data - index = 0; //index for result data set - int sameSetOffset = np.Shape.DimOffset[axis.Value]; - int increments = cur * post; - res.Data = new double[size]; - int start = 0; - double min = 0; - for (int i = 0; i < np.Size; i += increments) - { - for (int j = i; j < i + post; j++) - { - start = j; - min = np.Data[start]; - for (int k = 0; k < cur; k++) - { - min = Math.Min(min, np.Data[start]); - start += sameSetOffset; - } - res.Data[index++] = min; - } - } - } - return res; - } - } -} diff --git a/src/NumSharp.Core/Extensions/NumPy.min.cs b/src/NumSharp.Core/Extensions/NumPy.min.cs deleted file mode 100644 index 246338ffd..000000000 --- a/src/NumSharp.Core/Extensions/NumPy.min.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NumSharp.Core.Extensions -{ - public static partial class NumPyExtensions - { - public static NDArrayGeneric min(this NDArrayGeneric np) - { - return np.AMin(); - } - } -} diff --git a/src/NumSharp.Core/Math/NumPy.amax.cs b/src/NumSharp.Core/Math/NumPy.amax.cs index 20c008680..c287938b7 100644 --- a/src/NumSharp.Core/Math/NumPy.amax.cs +++ b/src/NumSharp.Core/Math/NumPy.amax.cs @@ -9,63 +9,7 @@ public partial class NumPy { public NDArray amax(NDArray nd, int? axis = null) { - var res = new NDArray(nd.dtype, nd.shape); - - if (axis == null) - { - res.Set(new double[1] { nd.Data().Max() }); - res.Storage.Shape = new Shape(new int[] { 1 }); - } - else - { - if (axis < 0 || axis >= nd.ndim) - throw new Exception("Invalid input: axis"); - int[] resShapes = new int[nd.ndim - 1]; - int index = 0; //index for result shape set - //axis departs the shape into three parts: prev, cur and post. They are all product of shapes - int prev = 1; - int cur = 1; - int post = 1; - int size = 1; //total number of the elements for result - //Calculate new Shape - for (int i = 0; i < nd.ndim; i++) - { - if (i == axis) - cur = nd.shape.Shapes[i]; - else - { - resShapes[index++] = nd.shape.Shapes[i]; - size *= nd.shape.Shapes[i]; - if (i < axis) - prev *= nd.shape.Shapes[i]; - else - post *= nd.shape.Shapes[i]; - } - } - res.Storage.Shape = new Shape(resShapes); - //Fill in data - index = 0; //index for result data set - int sameSetOffset = nd.shape.DimOffset[axis.Value]; - int increments = cur * post; - int start = 0; - double min = 0; - for (int i = 0; i < nd.size; i += increments) - { - for (int j = i; j < i + post; j++) - { - start = j; - min = nd.Data()[start]; - for (int k = 0; k < cur; k++) - { - min = Math.Max(min, nd.Data()[start]); - start += sameSetOffset; - } - res[index++] = min; - } - } - } - - return res; + return nd.amax(axis); } } } diff --git a/src/NumSharp.Core/Math/NumPy.amin.cs b/src/NumSharp.Core/Math/NumPy.amin.cs index 264fedadf..f8f964919 100644 --- a/src/NumSharp.Core/Math/NumPy.amin.cs +++ b/src/NumSharp.Core/Math/NumPy.amin.cs @@ -9,71 +9,7 @@ public partial class NumPy { public NDArray amin(NDArray nd, int? axis = null) { - NDArray res = null; - - if (axis == null) - { - res = new NDArray(nd.dtype,new Shape(new int[] { 1 })); - - Array resArray = Array.CreateInstance(nd.dtype,1); - resArray.SetValue(nd.Storage.GetData().Min(),0); - - res.Storage.SetData(resArray); - - } - else - { - if (axis < 0 || axis >= nd.ndim) - throw new Exception("Invalid input: axis"); - int[] resShapes = new int[nd.ndim - 1]; - int index = 0; //index for result shape set - //axis departs the shape into three parts: prev, cur and post. They are all product of shapes - int prev = 1; - int cur = 1; - int post = 1; - int size = 1; //total number of the elements for result - //Calculate new Shape - for (int i = 0; i < nd.ndim; i++) - { - if (i == axis) - cur = nd.shape.Shapes[i]; - else - { - resShapes[index++] = nd.shape.Shapes[i]; - size *= nd.shape.Shapes[i]; - if (i < axis) - prev *= nd.shape.Shapes[i]; - else - post *= nd.shape.Shapes[i]; - } - } - - //Fill in data - index = 0; //index for result data set - int sameSetOffset = nd.shape.DimOffset[axis.Value]; - int increments = cur * post; - int start = 0; - double min = 0; - - res = new NDArray(nd.dtype,new Shape(resShapes)); - - for (int i = 0; i < nd.size; i += increments) - { - for (int j = i; j < i + post; j++) - { - start = j; - min = nd.Data()[start]; - for (int k = 0; k < cur; k++) - { - min = Math.Min(min, nd.Data()[start]); - start += sameSetOffset; - } - res.Data()[index++] = min; - } - } - } - - return res; + return nd.amin(axis); } } } diff --git a/src/NumSharp.Core/NumPyGeneric.cs b/src/NumSharp.Core/NumPyGeneric.cs index 1ae8a70ab..f2ce702ed 100644 --- a/src/NumSharp.Core/NumPyGeneric.cs +++ b/src/NumSharp.Core/NumPyGeneric.cs @@ -11,20 +11,7 @@ namespace NumSharp.Core [Obsolete("please use NumPy")] public class NumPyGeneric { - public NDArrayGeneric absolute(NDArrayGeneric np) - { - return np.Absolute(); - } - - public NDArrayGeneric amax(NDArrayGeneric np, int? axis = null) - { - return np.AMax(axis); - } - - public NDArrayGeneric amin(NDArrayGeneric np, int? axis = null) - { - return np.AMin(axis); - } + public NDArrayGeneric arange(int stop) { diff --git a/src/NumSharp.Core/Extensions/NdArray.AMax.cs b/src/NumSharp.Core/Selection/NdArray.AMax.cs similarity index 52% rename from src/NumSharp.Core/Extensions/NdArray.AMax.cs rename to src/NumSharp.Core/Selection/NdArray.AMax.cs index a728b5720..fc45d8a70 100644 --- a/src/NumSharp.Core/Extensions/NdArray.AMax.cs +++ b/src/NumSharp.Core/Selection/NdArray.AMax.cs @@ -3,9 +3,9 @@ using System.Linq; using System.Text; -namespace NumSharp.Core.Extensions +namespace NumSharp.Core { - public static partial class NDArrayExtensions + public partial class NDArray { /// /// Return the maximum of an array or minimum along an axis @@ -13,23 +13,25 @@ public static partial class NDArrayExtensions /// /// /// - public static NDArrayGeneric AMax(this NDArrayGeneric np, int? axis = null) + public NDArray amax(int? axis = null) { - NDArrayGeneric res = new NDArrayGeneric(); + var res = new NDArray(dtype); + + double[] npArr = this.Storage.GetData(); + if (axis == null) { - double min = np.Data[0]; - for (int i = 0; i < np.Size; i++) - min = Math.Max(min, np.Data[i]); - res.Data = new double[1]; - res.Data[0] = min; - res.Shape = new Shape(new int[] { 1 }); + double min = npArr[0]; + for (int i = 0; i < npArr.Length; i++) + min = Math.Max(min, npArr[i]); + + res.Storage = NDStorage.CreateByArray(new double[1] {min}); } else { - if (axis < 0 || axis >= np.NDim) + if (axis < 0 || axis >= this.ndim) throw new Exception("Invalid input: axis"); - int[] resShapes = new int[np.Shape.Shapes.Count - 1]; + int[] resShapes = new int[this.shape.Shapes.Count - 1]; int index = 0; //index for result shape set //axis departs the shape into three parts: prev, cur and post. They are all product of shapes int prev = 1; @@ -37,42 +39,44 @@ public static NDArrayGeneric AMax(this NDArrayGeneric np, int? a int post = 1; int size = 1; //total number of the elements for result //Calculate new Shape - for (int i = 0; i < np.Shape.Shapes.Count; i++) + for (int i = 0; i < this.shape.Shapes.Count; i++) { if (i == axis) - cur = np.Shape.Shapes[i]; + cur = this.shape.Shapes[i]; else { - resShapes[index++] = np.Shape.Shapes[i]; - size *= np.Shape.Shapes[i]; + resShapes[index++] = this.shape.Shapes[i]; + size *= this.shape.Shapes[i]; if (i < axis) - prev *= np.Shape.Shapes[i]; + prev *= this.shape.Shapes[i]; else - post *= np.Shape.Shapes[i]; + post *= this.shape.Shapes[i]; } } - res.Shape = new Shape(resShapes); + res.Storage.Shape = new Shape(resShapes); //Fill in data index = 0; //index for result data set - int sameSetOffset = np.Shape.DimOffset[axis.Value]; + int sameSetOffset = this.shape.DimOffset[axis.Value]; int increments = cur * post; - res.Data = new double[size]; + double[] resData = new double[size]; //res.Data = new double[size]; int start = 0; double min = 0; - for (int i = 0; i < np.Size; i += increments) + for (int i = 0; i < this.size; i += increments) { for (int j = i; j < i + post; j++) { start = j; - min = np.Data[start]; + min = npArr[start]; for (int k = 0; k < cur; k++) { - min = Math.Max(min, np.Data[start]); + min = Math.Max(min, npArr[start]); start += sameSetOffset; } - res.Data[index++] = min; + resData[index++] = min; } } + res.Storage = NDStorage.CreateByArray(resData); + res.Storage.Shape = new Shape(resShapes); } return res; } diff --git a/src/NumSharp.Core/Selection/NdArray.AMin.cs b/src/NumSharp.Core/Selection/NdArray.AMin.cs new file mode 100644 index 000000000..edc60dac2 --- /dev/null +++ b/src/NumSharp.Core/Selection/NdArray.AMin.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NumSharp.Core +{ + public partial class NDArray + { + /// + /// Return the maximum of an array or minimum along an axis + /// + /// + /// + /// + public NDArray amin(int? axis = null) + { + var res = new NDArray(dtype); + + double[] npArr = this.Storage.GetData(); + + if (axis == null) + { + double min = npArr[0]; + for (int i = 0; i < npArr.Length; i++) + min = Math.Min(min, npArr[i]); + + res.Storage = NDStorage.CreateByArray(new double[1] {min}); + } + else + { + if (axis < 0 || axis >= this.ndim) + throw new Exception("Invalid input: axis"); + int[] resShapes = new int[this.shape.Shapes.Count - 1]; + int index = 0; //index for result shape set + //axis departs the shape into three parts: prev, cur and post. They are all product of shapes + int prev = 1; + int cur = 1; + int post = 1; + int size = 1; //total number of the elements for result + //Calculate new Shape + for (int i = 0; i < this.shape.Shapes.Count; i++) + { + if (i == axis) + cur = this.shape.Shapes[i]; + else + { + resShapes[index++] = this.shape.Shapes[i]; + size *= this.shape.Shapes[i]; + if (i < axis) + prev *= this.shape.Shapes[i]; + else + post *= this.shape.Shapes[i]; + } + } + res.Storage.Shape = new Shape(resShapes); + //Fill in data + index = 0; //index for result data set + int sameSetOffset = this.shape.DimOffset[axis.Value]; + int increments = cur * post; + double[] resData = new double[size]; //res.Data = new double[size]; + int start = 0; + double min = 0; + for (int i = 0; i < this.size; i += increments) + { + for (int j = i; j < i + post; j++) + { + start = j; + min = npArr[start]; + for (int k = 0; k < cur; k++) + { + min = Math.Min(min, npArr[start]); + start += sameSetOffset; + } + resData[index++] = min; + } + } + res.Storage = NDStorage.CreateByArray(resData); + res.Storage.Shape = new Shape(resShapes); + } + return res; + } + } +} diff --git a/test/NumSharp.UnitTest/Extensions/NDArray.AMax.Test.cs b/test/NumSharp.UnitTest/Selection/NDArray.AMax.Test.cs similarity index 75% rename from test/NumSharp.UnitTest/Extensions/NDArray.AMax.Test.cs rename to test/NumSharp.UnitTest/Selection/NDArray.AMax.Test.cs index a3f3ad36b..ce8695c5a 100644 --- a/test/NumSharp.UnitTest/Extensions/NDArray.AMax.Test.cs +++ b/test/NumSharp.UnitTest/Selection/NDArray.AMax.Test.cs @@ -10,45 +10,47 @@ namespace NumSharp.UnitTest.Extensions [TestClass] public class NDArrayAMaxTest { + [TestMethod] public void amax() { - var np = new NumPyGeneric(); + var np = new NumPy(); //no axis var n = np.arange(4).reshape(2, 2); - var n1 = np.amax(n); + var n1 = np.amax(n).MakeGeneric(); Assert.IsTrue(n1[0] == 3); //2D with axis - n1 = np.amax(n, 0); + n1 = np.amax(n, 0).MakeGeneric(); Assert.IsTrue(n1[0] == 2); Assert.IsTrue(n1[1] == 3); - n1 = np.amax(n, 1); + n1 = np.amax(n, 1).MakeGeneric(); Assert.IsTrue(n1[0] == 1); Assert.IsTrue(n1[1] == 3); //3D n = np.arange(24).reshape(4, 3, 2); - n1 = np.amax(n, 0); + n1 = np.amax(n, 0).MakeGeneric(); Assert.IsTrue(n1[0, 1] == 19); Assert.IsTrue(n1[2, 1] == 23); Assert.IsTrue(n1[1, 1] == 21); - n1 = np.amax(n, 1); + n1 = np.amax(n, 1).MakeGeneric(); Assert.IsTrue(n1[1, 1] == 11); Assert.IsTrue(n1[2, 1] == 17); Assert.IsTrue(n1[3, 0] == 22); //4D n = np.arange(24).reshape(2, 3, 2, 2); - n1 = np.amax(n, 1); + n1 = np.amax(n, 1).MakeGeneric(); Assert.IsTrue(n1[0, 0, 1] == 9); Assert.IsTrue(n1[1, 0, 1] == 21); Assert.IsTrue(n1[1, 1, 1] == 23); - n1 = np.amax(n, 3); + n1 = np.amax(n, 3).MakeGeneric(); Assert.IsTrue(n1[0, 1, 1] == 7); Assert.IsTrue(n1[1, 1, 1] == 19); Assert.IsTrue(n1[1, 2, 1] == 23); } + } } diff --git a/test/NumSharp.UnitTest/Extensions/NDArray.AMin.Test.cs b/test/NumSharp.UnitTest/Selection/NDArray.AMin.Test.cs similarity index 86% rename from test/NumSharp.UnitTest/Extensions/NDArray.AMin.Test.cs rename to test/NumSharp.UnitTest/Selection/NDArray.AMin.Test.cs index 6da595a99..97d2cbfe7 100644 --- a/test/NumSharp.UnitTest/Extensions/NDArray.AMin.Test.cs +++ b/test/NumSharp.UnitTest/Selection/NDArray.AMin.Test.cs @@ -12,39 +12,39 @@ public class NDArrayAMinTest [TestMethod] public void amin() { - var np = new NumPyGeneric(); + var np = new NumPy(); //no axis var n = np.arange(4).reshape(2, 2); - var n1 = np.amin(n); + var n1 = np.amin(n).MakeGeneric(); Assert.IsTrue(n1[0] == 0); //2D with axis - n1 = np.amin(n, 0); + n1 = np.amin(n, 0).MakeGeneric(); Assert.IsTrue(n1[0] == 0); Assert.IsTrue(n1[1] == 1); - n1 = np.amin(n, 1); + n1 = np.amin(n, 1).MakeGeneric(); Assert.IsTrue(n1[0] == 0); Assert.IsTrue(n1[1] == 2); //3D n = np.arange(24).reshape(4, 3, 2); - n1 = np.amin(n, 0); + n1 = np.amin(n, 0).MakeGeneric(); Assert.IsTrue(n1[0, 1] == 1); Assert.IsTrue(n1[2, 1] == 5); Assert.IsTrue(n1[1, 1] == 3); - n1 = np.amin(n, 1); + n1 = np.amin(n, 1).MakeGeneric(); Assert.IsTrue(n1[1, 1] == 7); Assert.IsTrue(n1[2, 1] == 13); Assert.IsTrue(n1[3, 0] == 18); //4D n = np.arange(24).reshape(2, 3, 2, 2); - n1 = np.amin(n, 1); + n1 = np.amin(n, 1).MakeGeneric(); Assert.IsTrue(n1[0, 0, 1] == 1); Assert.IsTrue(n1[1, 0, 1] == 13); Assert.IsTrue(n1[1, 1, 1] == 15); - n1 = np.amin(n, 3); + n1 = np.amin(n, 3).MakeGeneric(); Assert.IsTrue(n1[0, 1, 1] == 6); Assert.IsTrue(n1[1, 1, 1] == 18); Assert.IsTrue(n1[1, 2, 1] == 22); From 2b4eddf62dfef5bdb0878eeefda15e0c298f2b98 Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 10:09:27 +0100 Subject: [PATCH 2/7] Feat : array with image now works without generic --- src/NumSharp.Core/Creation/NumPy.array.cs | 24 ++++++++++++------- .../Creation/NdArray.Array.Test.cs | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/NumSharp.Core/Creation/NumPy.array.cs b/src/NumSharp.Core/Creation/NumPy.array.cs index f9d0cc67e..655a29aef 100644 --- a/src/NumSharp.Core/Creation/NumPy.array.cs +++ b/src/NumSharp.Core/Creation/NumPy.array.cs @@ -7,22 +7,30 @@ namespace NumSharp.Core { - public static partial class NumPyExtensions + public partial class NumPy { - public static NDArray array(this NumPy np, Array array, Type dtype = null, int ndim = 1) + public NDArray array(Array array, Type dtype = null, int ndim = 1) { dtype = (dtype == null) ? array.GetType().GetElementType() : dtype; var nd = new NDArray(dtype); - - nd.Storage = NDStorage.CreateByShapeAndType (dtype, new Shape(new int[] { array.Length })); - nd.Storage.SetData(array); + + if ((array.Rank == 1) && ( !array.GetType().GetElementType().IsArray )) + { + nd.Storage = NDStorage.CreateByShapeAndType (dtype, new Shape(new int[] { array.Length })); + nd.Storage.SetData(array); + } + else + { + throw new Exception("Method is not implemeneted for multidimensional arrays or jagged arrays."); + } + return nd; } - public static NDArray array(this NumPy np, System.Drawing.Bitmap image) + public NDArray array(System.Drawing.Bitmap image) { - var imageArray = new NDArray(typeof(T)); + var imageArray = new NDArray(typeof(Byte)); var bmpd = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, image.PixelFormat); var dataSize = bmpd.Stride * bmpd.Height; @@ -37,7 +45,7 @@ public static NDArray array(this NumPy np, System.Drawing.Bitmap image) return imageArray; } - public static NDArray array(this NumPy np, T[][] data) + public NDArray array(T[][] data) { int size = data.Length * data[0].Length; var all = new T[size]; diff --git a/test/NumSharp.UnitTest/Creation/NdArray.Array.Test.cs b/test/NumSharp.UnitTest/Creation/NdArray.Array.Test.cs index 5f8b70b5d..c28817332 100644 --- a/test/NumSharp.UnitTest/Creation/NdArray.Array.Test.cs +++ b/test/NumSharp.UnitTest/Creation/NdArray.Array.Test.cs @@ -52,7 +52,7 @@ public void ArrayImage() if (System.IO.File.Exists(imagePath)) { var image = new System.Drawing.Bitmap(imagePath); - var imageNDArray = np.array(image); + var imageNDArray = np.array(image); Assert.IsTrue(imageNDArray.Data(0, 0, 0) == 255); Assert.IsTrue(imageNDArray.Data(0, 0, 1) == 253); From df439b755879cc9701c22d60d98d289ce05c758b Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 10:09:49 +0100 Subject: [PATCH 3/7] Feat : add method signature without dtype --- src/NumSharp.Core/Creation/NdArray.Ones.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/NumSharp.Core/Creation/NdArray.Ones.cs b/src/NumSharp.Core/Creation/NdArray.Ones.cs index 92d48b75f..55148e230 100644 --- a/src/NumSharp.Core/Creation/NdArray.Ones.cs +++ b/src/NumSharp.Core/Creation/NdArray.Ones.cs @@ -22,5 +22,9 @@ public NDArray ones(Type dtype = null, params int[] shapes) return this; } + public NDArray ones(params int[] shapes) + { + return this.ones(typeof(double),shapes); + } } } \ No newline at end of file From 4294e05bd4c552c34aaecbbaab38abf5bcdccca1 Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 10:11:51 +0100 Subject: [PATCH 4/7] Style : new location --- src/NumSharp.Core/Extensions/NDArray.Std.cs | 59 ------------------- .../Extensions/NdArray.Absolute.cs | 24 -------- 2 files changed, 83 deletions(-) delete mode 100644 src/NumSharp.Core/Extensions/NDArray.Std.cs delete mode 100644 src/NumSharp.Core/Extensions/NdArray.Absolute.cs diff --git a/src/NumSharp.Core/Extensions/NDArray.Std.cs b/src/NumSharp.Core/Extensions/NDArray.Std.cs deleted file mode 100644 index 28cfb4c5b..000000000 --- a/src/NumSharp.Core/Extensions/NDArray.Std.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NumSharp.Core.Extensions -{ - public static partial class NDArrayExtensions - { - public static NDArrayGeneric Std(this NDArrayGeneric np, int axis = -1) - { - var std = new NDArrayGeneric(); - - var mean = np.Mean(axis); - - // axis == -1: DEFAULT; to compute the standard deviation of the flattened array. - if (axis == -1) - { - var sum = np.Data.Select(d => Math.Pow(Math.Abs(d - mean.Data[0]), 2)).Sum(); - - std.Data = new double[]{ Math.Sqrt(sum / np.Size) }; - } - // to compute mean by compressing row and row - else if (axis == 0) - { - double[] sumVec = new double[np.Shape.Shapes[1]]; - for (int d = 0; d < np.Shape.Shapes[0]; d++) - { - for (int p = 0; p < np.Shape.Shapes[1]; p++) - { - sumVec[p] += np[d,p]; - } - } - var puffer = mean.Data.ToList(); - for (int d = 0; d < np.Shape.Shapes[1]; d++) - { - puffer.Add(sumVec[d] / np.Shape.Shapes[0]); - } - mean.Data = puffer.ToArray(); - } - else if (axis == 1) - { - var puffer = mean.Data.ToList(); - for (int d = 0; d < np.Shape.Shapes[0]; d++) - { - double rowSum = 0; - for (int p = 0; p < np.Shape.Shapes[1]; p++) - { - rowSum += np[d,p]; - } - puffer.Add(rowSum / np.Shape.Shapes[1]); - } - mean.Data = puffer.ToArray(); - } - - return std; - } - } -} diff --git a/src/NumSharp.Core/Extensions/NdArray.Absolute.cs b/src/NumSharp.Core/Extensions/NdArray.Absolute.cs deleted file mode 100644 index 787c14a08..000000000 --- a/src/NumSharp.Core/Extensions/NdArray.Absolute.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NumSharp.Core.Extensions -{ - public static partial class NDArrayExtensions - { - public static NDArrayGeneric Absolute(this NDArrayGeneric np) - { - NDArrayGeneric res = new NDArrayGeneric - { - Shape = np.Shape, - Data = new double[np.Size] - }; - for (int i = 0; i < np.Size; i++) - { - res.Data[i] = Math.Abs(np.Data[i]); - } - return res; - } - } -} From 818427d1e2312d6a79ac0c776b52d8ce39337f0b Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 13:16:23 +0100 Subject: [PATCH 5/7] Feat : Add dtype check --- src/NumSharp.Core/Math/NdArray.Convolve.cs | 2 +- src/NumSharp.Core/NDStorage.cs | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/NumSharp.Core/Math/NdArray.Convolve.cs b/src/NumSharp.Core/Math/NdArray.Convolve.cs index 55dd03991..c602d51e1 100644 --- a/src/NumSharp.Core/Math/NdArray.Convolve.cs +++ b/src/NumSharp.Core/Math/NdArray.Convolve.cs @@ -24,7 +24,7 @@ public NDArray Convolve(NDArray numSharpArray2, string mode = "full" ) if (shape.NDim > 1) throw new IncorrectShapeException(); - var numSharpReturn = new NDArray(this.dtype); + var numSharpReturn = new NDArray(typeof(double)); double[] np1 = this.Storage.GetData(); double[] np2 = numSharpArray2.Storage.GetData(); diff --git a/src/NumSharp.Core/NDStorage.cs b/src/NumSharp.Core/NDStorage.cs index 125f8a79f..b975a21ce 100644 --- a/src/NumSharp.Core/NDStorage.cs +++ b/src/NumSharp.Core/NDStorage.cs @@ -64,8 +64,13 @@ public static NDStorage CreateByShapeAndType(Type dtype,Shape shape) } public static NDStorage CreateByArray(Array values) { - Type dtype = values.GetType().GetElementType(); - + Type dtype = null; + + if ( !values.GetType().GetElementType().IsArray ) + dtype = values.GetType().GetElementType(); + else + throw new IncorrectShapeException(); + int[] dims = new int[values.Rank]; for (int idx = 0; idx < dims.Length;idx++) @@ -74,6 +79,8 @@ public static NDStorage CreateByArray(Array values) var storage = NDStorage.CreateByShapeAndType(dtype,new Shape(dims)); storage.values = Array.CreateInstance(dtype,values.Length); + storage.SetData(values); + return storage; } /// From 24e78951012adb99820102c4aba233a744335d15 Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 13:16:59 +0100 Subject: [PATCH 6/7] Feat : Add Shape Test + Compution indexes by 1D array index --- src/NumSharp.Core/Shape.cs | 26 ++++++++++++++++++++++++++ test/NumSharp.UnitTest/Shape.Test.cs | 27 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/NumSharp.UnitTest/Shape.Test.cs diff --git a/src/NumSharp.Core/Shape.cs b/src/NumSharp.Core/Shape.cs index c3e1e2767..26f134229 100644 --- a/src/NumSharp.Core/Shape.cs +++ b/src/NumSharp.Core/Shape.cs @@ -8,6 +8,7 @@ public partial class Shape { private readonly IReadOnlyList shape; private readonly IReadOnlyList dimOffset; + private readonly int dimOffsetTotal; public int Size { @@ -37,6 +38,7 @@ public Shape(params int[] shape) { temp[i - 1] = temp[i] * shape[i]; } + dimOffset = temp; } @@ -67,6 +69,30 @@ public int GetIndexInShape(params int[] select) return idx; } + public int[] GetDimIndexOutShape(int select) + { + int[] dimIndexes = null; + if (this.dimOffset.Count == 1) + dimIndexes = new int[] {select}; + else if (this.dimOffset.Count == 2) + { + dimIndexes = new int[dimOffset.Count]; + + int remaining = select; + + for (int idx = 0;idx < dimOffset.Count;idx++) + { + dimIndexes[idx] = remaining / dimOffset[idx]; + remaining -= (dimIndexes[idx] * dimOffset[idx] ); + } + } + else + { + throw new IncorrectShapeException(); + } + + return dimIndexes; + } public int UniShape => shape[0]; diff --git a/test/NumSharp.UnitTest/Shape.Test.cs b/test/NumSharp.UnitTest/Shape.Test.cs new file mode 100644 index 000000000..0c1c5e0f9 --- /dev/null +++ b/test/NumSharp.UnitTest/Shape.Test.cs @@ -0,0 +1,27 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; +using NumSharp.Core.Extensions; +using System.Linq; +using NumSharp.Core; + +namespace NumSharp.UnitTest +{ + [TestClass] + public class NDStorageTest + { + [TestMethod] + public void Index() + { + var shape0 = new Shape(4,3); + + int idx0 = shape0.GetIndexInShape(2,1); + int[] idx00 = shape0.GetDimIndexOutShape(idx0); + + Assert.IsTrue(idx00[0] == 2); + Assert.IsTrue(idx00[1] == 1); + + } + } +} From ff74d80185b1e36712de227768acfd2284d343b0 Mon Sep 17 00:00:00 2001 From: dotchris90 Date: Tue, 4 Dec 2018 13:18:47 +0100 Subject: [PATCH 7/7] Fix : now work with non generic --- test/NumSharp.Benchmark/np.amin.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/NumSharp.Benchmark/np.amin.cs b/test/NumSharp.Benchmark/np.amin.cs index c6aca9166..54c9174a2 100644 --- a/test/NumSharp.Benchmark/np.amin.cs +++ b/test/NumSharp.Benchmark/np.amin.cs @@ -12,13 +12,13 @@ namespace NumSharp.Benchmark [MinColumn, MaxColumn, MeanColumn, MedianColumn] public class npamin { - private NumPyGeneric np; - private NDArrayGeneric nd; + private NumPy np; + private NDArray nd; [GlobalSetup] public void Setup() { - np = new NumPyGeneric(); + np = new NumPy(); nd = np.arange(1000 * 8 * 8 * 8).reshape(1000, 8, 8, 8); } @@ -31,9 +31,9 @@ public void min() [Benchmark] public void amin0axis() { - var nd2 = new NDArrayGeneric(); + var nd2 = new NDArray(typeof(double)); nd2 = np.arange(1000 * 8 * 8 * 8).reshape(1000, 8, 8, 8); - //var nd3 = nd2.AMin(0); + var nd3 = nd2.amin(0); } [Benchmark]