public static NDArray matmul(NDArray a, NDArray b) { if (a.ndim == b.ndim && a.ndim == 2) { var nd = new NDArray(a.dtype, new Shape(a.shape[0], b.shape[1])); switch (nd.dtype.Name) { case "Int32": Parallel.ForEach(Enumerable.Range(0, nd.shape[0]), (row) => { for (int col = 0; col < nd.shape[1]; col++) { int sum = 0; for (int s = 0; s < nd.shape[0]; s++) { sum += a.Data <int>(row, s) * b.Data <int>(s, col); } nd[row, col] = sum; } }); break; case "Single": Parallel.ForEach(Enumerable.Range(0, nd.shape[0]), (row) => { for (int col = 0; col < nd.shape[1]; col++) { float sum = 0; for (int s = 0; s < nd.shape[0]; s++) { sum += a.Data <float>(row, s) * b.Data <float>(s, col); } nd[row, col] = sum; } }); break; case "Double": Parallel.ForEach(Enumerable.Range(0, nd.shape[0]), (row) => { for (int col = 0; col < nd.shape[1]; col++) { double sum = 0; for (int s = 0; s < nd.shape[0]; s++) { sum += a.Data <double>(row, s) * b.Data <double>(s, col); } nd[row, col] = sum; } }); break; } return(nd); } throw new NotImplementedException("matmul"); }
/// <summary> /// Matrix or vector product between given NDArray and 2nd one. /// if both NDArrays are 1D, scalar product is returned independend of shape /// if both NDArrays are 2D matrix product is returned. /// </summary> /// <param name="nd2">2nd NDArray</param> /// <returns>Scalarproduct or matrix prod</returns> public NDArray dot(NDArray nd2) { if (ndim == 0 && nd2.ndim == 0) { switch (dtype.Name) { case "Int32": return(nd2.Data <int>(0) * Data <int>(0)); } } else if (ndim == 1 && nd2.ndim == 1) { int sum = 0; switch (dtype.Name) { case "Int32": for (int i = 0; i < size; i++) { sum += Data <int>(i) * nd2.Data <int>(i); } break; } return(sum); } else if (ndim == 2 && nd2.ndim == 1) { var nd = new NDArray(dtype, new Shape(shape[0])); switch (dtype.Name) { case "Int32": for (int i = 0; i < shape[0]; i++) { for (int j = 0; j < nd2.shape[0]; j++) { nd.Data <int>()[i] += Data <int>(i, j) * nd2.Data <int>(j); } } break; } return(nd); } else if (ndim == 2 && nd2.ndim == 2) { return(np.matmul(this, nd2)); } throw new NotImplementedException($"dot {ndim} * {nd2.ndim}"); }
public static NDArray prod(NDArray nd, int axis = -1, Type dtype = null) { NDArray result = null; if (nd.size == 0) { return(1); } if (axis == -1) { switch (nd.dtype.Name) { case "Int32": { int prod = 1; for (int i = 0; i < nd.size; i++) { prod *= nd.Data <int>(i); } result = prod; } break; case "Int64": { long prod = 1; for (int i = 0; i < nd.size; i++) { prod *= nd.Data <long>(i); } result = prod; } break; } } else { throw new NotImplementedException($"np.prod axis {axis}"); } return(result); }
private NDArray setValue1D <T>(NDArray indexes) { var buf = Data <T>(); var idx = indexes.Data <int>(); var values = new T[indexes.size]; Parallel.ForEach(Enumerable.Range(0, indexes.size), (row) => { values[row] = buf[idx[row]]; }); return(new NDArray(values, indexes.size)); }
private NDArray setValue2D <T>(NDArray indexes) { var buf = Data <T>(); var idx = indexes.Data <int>(); var selectedValues = new NDArray(this.dtype, new Shape(indexes.size, shape[1])); Parallel.ForEach(Enumerable.Range(0, selectedValues.shape[0]), (row) => { for (int col = 0; col < selectedValues.shape[1]; col++) { selectedValues[row, col] = buf[Storage.Shape.GetIndexInShape(idx[row], col)]; } }); return(selectedValues); }
public static NDArray arange(int start, int stop, int step = 1) { if (start > stop) { throw new Exception("parameters invalid, start is greater than stop."); } int length = (int)Math.Ceiling((stop - start + 0.0) / step); int index = 0; var nd = new NDArray(np.int32, new Shape(length)); if (nd.Data <int>() is int[] a) { for (int i = start; i < stop; i += step) { a[index++] = i; } } return(nd); }
private NDArray setValue4D <T>(NDArray indexes) { var buf = Data <T>(); var selectedValues = new NDArray(this.dtype, new Shape(indexes.size, shape[1], shape[2], shape[3])); var idx = indexes.Data <int>(); Parallel.ForEach(Enumerable.Range(0, selectedValues.shape[0]), (item) => { for (int row = 0; row < selectedValues.shape[1]; row++) { for (int col = 0; col < selectedValues.shape[2]; col++) { for (int channel = 0; channel < selectedValues.shape[3]; channel++) { selectedValues[item, row, col, channel] = buf[Storage.Shape.GetIndexInShape(idx[item], row, col, channel)]; } } } }); return(selectedValues); }
public static NDArray repeat(NDArray nd, int repeats, int axis = -1) { int size = nd.size * repeats; // scalar switch (nd.dtype.Name) { case "Int32": { var nd2 = new NDArray(new int[size], new Shape(size)); for (int i = 0; i < nd.size; i++) { for (int j = 0; j < repeats; j++) { nd2[i * repeats + j] = nd.Data <int>(i); } } return(nd2); } } throw new NotImplementedException("np.repeat"); }
public NDArray this[NDArray select] => this[select.Data <int>().ToList()];
/// <summary> /// Matrix or vector product between given NDArray and 2nd one. /// if both NDArrays are 1D, scalar product is returned independend of shape /// if both NDArrays are 2D matrix product is returned. /// </summary> /// <param name="nd2">2nd NDArray</param> /// <returns>Scalarproduct or matrix prod</returns> public NDArray dot(NDArray nd2) { var pufferShape = nd2.Storage.Shape; // in case must do a reshape var oldStorage1 = this.Storage; var oldStorage2 = nd2.Storage; if ((this.ndim == 0) & (nd2.ndim == 0)) { if (this.dtype == typeof(int)) { var ret = this.Data <int>()[0] * nd2.Data <int>()[0]; return(new NDArray(new int[] { ret }).reshape()); } } if ((this.ndim == 1) & (nd2.ndim == 1)) { if (this.shape[0] != nd2.shape[0]) { throw new IncorrectShapeException(); } else { this.Storage = new NDStorage(); this.Storage.Allocate(oldStorage1.DType, new Shape(1, oldStorage1.GetData().Length), 1); this.Storage.SetData(oldStorage1.GetData()); nd2.Storage = new NDStorage(); nd2.Storage.Allocate(oldStorage2.DType, new Shape(oldStorage2.GetData().Length, 1), 1); nd2.Storage.SetData(oldStorage2.GetData()); } } else if (this.shape[1] != nd2.shape[0]) { throw new IncorrectShapeException(); } if ((this.ndim == 2) & (nd2.ndim == 1)) { var pufferList = pufferShape.Dimensions.ToList(); pufferList.Add(1); nd2.Storage.Reshape(pufferList.ToArray()); } int iterator = this.shape[1]; int dim0 = this.shape[0]; int dim1 = nd2.shape[1]; var prod = new NDArray(this.Storage.DType, new Shape(dim0, dim1)); Array nd1SystemArray = this.Storage.GetData(); switch (nd1SystemArray) { case int[] nd1Array: { int[] result = prod.Storage.GetData <int>(); int[] nd2Array = nd2.Storage.GetData <int>(); for (int idx = 0; idx < prod.size; idx++) { int puffer1 = idx % dim0; int puffer2 = idx / dim0; int puffer3 = puffer2 * iterator; for (int kdx = 0; kdx < iterator; kdx++) { result[idx] += nd2Array[puffer3 + kdx] * nd1Array[dim0 * kdx + puffer1]; } } break; } case double[] nd1Array: { double[] result = prod.Storage.GetData <double>(); double[] nd2Array = nd2.Storage.GetData <double>(); for (int idx = 0; idx < prod.size; idx++) { int puffer1 = idx % dim0; int puffer2 = idx / dim0; int puffer3 = puffer2 * iterator; for (int kdx = 0; kdx < iterator; kdx++) { result[idx] += nd2Array[puffer3 + kdx] * nd1Array[dim0 * kdx + puffer1]; } } break; } case float[] nd1Array: { float[] result = prod.Storage.GetData <float>(); float[] nd2Array = nd2.Storage.GetData <float>(); for (int idx = 0; idx < prod.size; idx++) { int puffer1 = idx % dim0; int puffer2 = idx / dim0; int puffer3 = puffer2 * iterator; for (int kdx = 0; kdx < iterator; kdx++) { result[idx] += nd2Array[puffer3 + kdx] * nd1Array[dim0 * kdx + puffer1]; } } break; } case Complex[] nd1Array: { Complex[] result = prod.Storage.GetData <Complex>(); Complex[] nd2Array = nd2.Storage.GetData <Complex>(); for (int idx = 0; idx < prod.size; idx++) { int puffer1 = idx % dim0; int puffer2 = idx / dim0; int puffer3 = puffer2 * iterator; for (int kdx = 0; kdx < iterator; kdx++) { result[idx] += nd2Array[puffer3 + kdx] * nd1Array[dim0 * kdx + puffer1]; } } break; } case Quaternion[] nd1Array: { Quaternion[] result = prod.Storage.GetData <Quaternion>(); Quaternion[] nd2Array = nd2.Storage.GetData <Quaternion>(); for (int idx = 0; idx < prod.size; idx++) { int puffer1 = idx % dim0; int puffer2 = idx / dim0; int puffer3 = puffer2 * iterator; for (int kdx = 0; kdx < iterator; kdx++) { result[idx] += nd2Array[puffer3 + kdx] * nd1Array[dim0 * kdx + puffer1]; } } break; } default: { throw new NotImplementedException(); } } if ((this.ndim == 1) & (nd2.ndim == 1)) { this.Storage.Reshape(this.Storage.GetData().Length); nd2.Storage.Reshape(nd2.Storage.GetData().Length); prod.Storage.Reshape(1); } this.Storage = oldStorage1; nd2.Storage = oldStorage2; return(prod); }