| @@ -0,0 +1,22 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.NumPy | |||
| { | |||
| public partial class NDArray | |||
| { | |||
| public override bool Equals(object obj) | |||
| { | |||
| return obj switch | |||
| { | |||
| int val => GetAtIndex<int>(0) == val, | |||
| long val => GetAtIndex<long>(0) == val, | |||
| float val => GetAtIndex<float>(0) == val, | |||
| double val => GetAtIndex<double>(0) == val, | |||
| _ => base.Equals(obj) | |||
| }; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,42 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.NumPy | |||
| { | |||
| public partial class NDArray | |||
| { | |||
| public static implicit operator NDArray(Array array) | |||
| => new NDArray(array); | |||
| public static implicit operator bool(NDArray nd) | |||
| => nd._tensor.ToArray<bool>()[0]; | |||
| public static implicit operator byte[](NDArray nd) | |||
| => nd.ToByteArray(); | |||
| public static implicit operator int(NDArray nd) | |||
| => nd._tensor.ToArray<int>()[0]; | |||
| public static implicit operator double(NDArray nd) | |||
| => nd._tensor.ToArray<double>()[0]; | |||
| public static implicit operator NDArray(bool value) | |||
| => new NDArray(value); | |||
| public static implicit operator NDArray(int value) | |||
| => new NDArray(value); | |||
| public static implicit operator NDArray(float value) | |||
| => new NDArray(value); | |||
| public static implicit operator NDArray(double value) | |||
| => new NDArray(value); | |||
| public static implicit operator Tensor(NDArray nd) | |||
| => nd._tensor; | |||
| public static implicit operator NDArray(Tensor tensor) | |||
| => new NDArray(tensor); | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| using System; | |||
| using System.Collections; | |||
| using System.Collections.Generic; | |||
| using System.Numerics; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.NumPy | |||
| { | |||
| public partial class np | |||
| { | |||
| public static NDArray log(NDArray x) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray prod(NDArray array, int? axis = null, Type dtype = null, bool keepdims = false) | |||
| => tf.reduce_prod(ops.convert_to_tensor(array)); | |||
| public static NDArray prod<T>(params T[] array) where T : unmanaged | |||
| => tf.reduce_prod(ops.convert_to_tensor(array)); | |||
| public static NDArray multiply(in NDArray x1, in NDArray x2) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray sum(NDArray x1) | |||
| => throw new NotImplementedException(""); | |||
| } | |||
| } | |||
| @@ -17,22 +17,32 @@ namespace Tensorflow.NumPy | |||
| public NDArray(bool value) | |||
| { | |||
| _tensor = ops.convert_to_tensor(value); | |||
| } | |||
| public NDArray(byte value) | |||
| { | |||
| _tensor = ops.convert_to_tensor(value); | |||
| } | |||
| public NDArray(float value) | |||
| public NDArray(int value) | |||
| { | |||
| _tensor = ops.convert_to_tensor(value); | |||
| } | |||
| public NDArray(float value) | |||
| { | |||
| _tensor = ops.convert_to_tensor(value); | |||
| } | |||
| public NDArray(double value) | |||
| { | |||
| _tensor = ops.convert_to_tensor(value); | |||
| } | |||
| public NDArray(Array value, Shape shape = null) | |||
| { | |||
| _tensor = ops.convert_to_tensor(value); | |||
| } | |||
| public NDArray(Type dtype, Shape shape) | |||
| @@ -135,39 +145,6 @@ namespace Tensorflow.NumPy | |||
| public T[] ToArray<T>() where T : unmanaged | |||
| => _tensor.ToArray<T>(); | |||
| public static implicit operator NDArray(Array array) | |||
| => new NDArray(array); | |||
| public static implicit operator bool(NDArray nd) | |||
| => nd._tensor.ToArray<bool>()[0]; | |||
| public static implicit operator int(NDArray nd) | |||
| => nd._tensor.ToArray<int>()[0]; | |||
| public static implicit operator NDArray(bool value) | |||
| => new NDArray(value); | |||
| public static implicit operator NDArray(float value) | |||
| => new NDArray(value); | |||
| public static implicit operator NDArray(double value) | |||
| => new NDArray(value); | |||
| public static implicit operator NDArray(byte[] value) | |||
| => new NDArray(value); | |||
| public static implicit operator byte[](NDArray nd) | |||
| => nd.ToByteArray(); | |||
| public static implicit operator NDArray(int[] value) | |||
| => new NDArray(value, new Shape(value.Length)); | |||
| public static implicit operator NDArray(float[] value) | |||
| => new NDArray(value); | |||
| public static implicit operator Tensor(NDArray nd) | |||
| => nd._tensor; | |||
| public static NDArray operator /(NDArray x, NDArray y) => throw new NotImplementedException(""); | |||
| public override string ToString() | |||
| @@ -84,31 +84,12 @@ namespace Tensorflow.NumPy | |||
| public static NDArray frombuffer(byte[] bytes, string dtype) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray prod(in NDArray a, int? axis = null, Type dtype = null, bool keepdims = false) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray prod(params int[] array) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray multiply(in NDArray x1, in NDArray x2) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray sum(NDArray x1) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray squeeze(NDArray x1) | |||
| => throw new NotImplementedException(""); | |||
| public static NDArray log(NDArray x) | |||
| => throw new NotImplementedException(""); | |||
| public static bool allclose(NDArray a, NDArray b, double rtol = 1.0E-5, double atol = 1.0E-8, | |||
| bool equal_nan = false) => throw new NotImplementedException(""); | |||
| public static class random | |||
| { | |||
| public static NDArray permutation(int x) | |||
| @@ -103,6 +103,10 @@ namespace Tensorflow | |||
| fixed (void* addr = &val[0]) | |||
| _handle = TF_NewTensor(shape, dtype, addr, length); | |||
| break; | |||
| case double[,] val: | |||
| fixed (void* addr = &val[0, 0]) | |||
| _handle = TF_NewTensor(shape, dtype, addr, length); | |||
| break; | |||
| default: | |||
| throw new NotImplementedException(""); | |||
| } | |||
| @@ -159,7 +159,7 @@ namespace Tensorflow | |||
| case EagerTensor val: | |||
| return val; | |||
| case NDArray val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| return (EagerTensor)val; | |||
| case Shape val: | |||
| return new EagerTensor(val.dims, new Shape(val.ndim)); | |||
| case TensorShape val: | |||
| @@ -172,49 +172,27 @@ namespace Tensorflow | |||
| return new EagerTensor(new[] { val }, Shape.Scalar); | |||
| case byte val: | |||
| return new EagerTensor(new[] { val }, Shape.Scalar); | |||
| case byte[] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case byte[,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case byte[,,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case int val: | |||
| return new EagerTensor(new[] { val }, Shape.Scalar); | |||
| case int[] val: | |||
| return new EagerTensor(val, new Shape(val.Length)); | |||
| case int[,] val: | |||
| return new EagerTensor(val, new Shape(val.GetLength(0), val.GetLength(1))); | |||
| case int[,,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case long val: | |||
| return new EagerTensor(new[] { val }, Shape.Scalar); | |||
| case long[] val: | |||
| return new EagerTensor(val, new Shape(val.Length)); | |||
| case long[,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case long[,,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case float val: | |||
| return new EagerTensor(new[] { val }, Shape.Scalar); | |||
| case float[] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case float[,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case float[,,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case double val: | |||
| return new EagerTensor(new[] { val }, Shape.Scalar); | |||
| case double[] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case double[,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case double[,,] val: | |||
| return new EagerTensor(val, ctx.DeviceName); | |||
| case Array val: | |||
| return new EagerTensor(val, GetArrayDims(val)); | |||
| default: | |||
| throw new NotImplementedException($"convert_to_eager_tensor {value.GetType()}"); | |||
| } | |||
| } | |||
| static Shape GetArrayDims(Array array) | |||
| { | |||
| var dims = range(array.Rank).Select(x => (long)array.GetLength(x)).ToArray(); | |||
| return new Shape(dims); | |||
| } | |||
| /// <summary> | |||
| /// Function to convert TensorShape to Tensor. | |||
| /// </summary> | |||
| @@ -31,6 +31,7 @@ namespace Tensorflow | |||
| public static Tensor operator -(ResourceVariable x, ResourceVariable y) => x.value() - y.value(); | |||
| public static Tensor operator *(ResourceVariable x, ResourceVariable y) => x.value() * y.value(); | |||
| public static Tensor operator *(ResourceVariable x, Tensor y) => x.value() * y; | |||
| public static Tensor operator *(ResourceVariable x, NDArray y) => x.value() * y; | |||
| public static Tensor operator <(ResourceVariable x, Tensor y) => x.value() < y; | |||
| @@ -157,7 +157,6 @@ namespace Tensorflow | |||
| RefVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref), | |||
| ResourceVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref), | |||
| TensorShape ts => constant_op.constant(ts.dims, dtype: dtype, name: name), | |||
| int[] dims => constant_op.constant(dims, dtype: dtype, name: name), | |||
| string str => constant_op.constant(str, dtype: tf.@string, name: name), | |||
| string[] str => constant_op.constant(str, dtype: tf.@string, name: name), | |||
| IEnumerable<object> objects => array_ops._autopacking_conversion_function(objects, dtype: dtype, name: name), | |||
| @@ -0,0 +1,26 @@ | |||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using Tensorflow.NumPy; | |||
| namespace TensorFlowNET.UnitTest.Numpy | |||
| { | |||
| /// <summary> | |||
| /// https://numpy.org/doc/stable/reference/generated/numpy.prod.html | |||
| /// </summary> | |||
| [TestClass] | |||
| public class NumpyMathTest : EagerModeTestBase | |||
| { | |||
| [TestMethod] | |||
| public void prod() | |||
| { | |||
| var p = np.prod(1.0, 2.0); | |||
| Assert.AreEqual(p, 2.0); | |||
| p = np.prod(new[,] { { 1.0, 2.0 }, { 3.0, 4.0 } }); | |||
| Assert.AreEqual(p, 24.0); | |||
| } | |||
| } | |||
| } | |||