Skip to content

Commit 7f387d0

Browse files
committed
np.prod
1 parent 3231500 commit 7f387d0

10 files changed

Lines changed: 144 additions & 87 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using static Tensorflow.Binding;
5+
6+
namespace Tensorflow.NumPy
7+
{
8+
public partial class NDArray
9+
{
10+
public override bool Equals(object obj)
11+
{
12+
return obj switch
13+
{
14+
int val => GetAtIndex<int>(0) == val,
15+
long val => GetAtIndex<long>(0) == val,
16+
float val => GetAtIndex<float>(0) == val,
17+
double val => GetAtIndex<double>(0) == val,
18+
_ => base.Equals(obj)
19+
};
20+
}
21+
}
22+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Tensorflow.NumPy
6+
{
7+
public partial class NDArray
8+
{
9+
public static implicit operator NDArray(Array array)
10+
=> new NDArray(array);
11+
12+
public static implicit operator bool(NDArray nd)
13+
=> nd._tensor.ToArray<bool>()[0];
14+
15+
public static implicit operator byte[](NDArray nd)
16+
=> nd.ToByteArray();
17+
18+
public static implicit operator int(NDArray nd)
19+
=> nd._tensor.ToArray<int>()[0];
20+
21+
public static implicit operator double(NDArray nd)
22+
=> nd._tensor.ToArray<double>()[0];
23+
24+
public static implicit operator NDArray(bool value)
25+
=> new NDArray(value);
26+
27+
public static implicit operator NDArray(int value)
28+
=> new NDArray(value);
29+
30+
public static implicit operator NDArray(float value)
31+
=> new NDArray(value);
32+
33+
public static implicit operator NDArray(double value)
34+
=> new NDArray(value);
35+
36+
public static implicit operator Tensor(NDArray nd)
37+
=> nd._tensor;
38+
39+
public static implicit operator NDArray(Tensor tensor)
40+
=> new NDArray(tensor);
41+
}
42+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Numerics;
5+
using System.Text;
6+
using static Tensorflow.Binding;
7+
8+
namespace Tensorflow.NumPy
9+
{
10+
public partial class np
11+
{
12+
public static NDArray log(NDArray x)
13+
=> throw new NotImplementedException("");
14+
15+
public static NDArray prod(NDArray array, int? axis = null, Type dtype = null, bool keepdims = false)
16+
=> tf.reduce_prod(ops.convert_to_tensor(array));
17+
18+
public static NDArray prod<T>(params T[] array) where T : unmanaged
19+
=> tf.reduce_prod(ops.convert_to_tensor(array));
20+
21+
public static NDArray multiply(in NDArray x1, in NDArray x2)
22+
=> throw new NotImplementedException("");
23+
24+
public static NDArray sum(NDArray x1)
25+
=> throw new NotImplementedException("");
26+
}
27+
}

src/TensorFlowNET.Core/Numpy/NDArray.cs

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,32 @@ public partial class NDArray
1717

1818
public NDArray(bool value)
1919
{
20+
_tensor = ops.convert_to_tensor(value);
21+
}
2022

23+
public NDArray(byte value)
24+
{
25+
_tensor = ops.convert_to_tensor(value);
2126
}
2227

23-
public NDArray(float value)
28+
public NDArray(int value)
2429
{
30+
_tensor = ops.convert_to_tensor(value);
31+
}
2532

33+
public NDArray(float value)
34+
{
35+
_tensor = ops.convert_to_tensor(value);
2636
}
2737

2838
public NDArray(double value)
2939
{
30-
40+
_tensor = ops.convert_to_tensor(value);
3141
}
3242

3343
public NDArray(Array value, Shape shape = null)
3444
{
35-
45+
_tensor = ops.convert_to_tensor(value);
3646
}
3747

3848
public NDArray(Type dtype, Shape shape)
@@ -135,39 +145,6 @@ public T[] Data<T>() where T : unmanaged
135145
public T[] ToArray<T>() where T : unmanaged
136146
=> _tensor.ToArray<T>();
137147

138-
public static implicit operator NDArray(Array array)
139-
=> new NDArray(array);
140-
141-
public static implicit operator bool(NDArray nd)
142-
=> nd._tensor.ToArray<bool>()[0];
143-
144-
public static implicit operator int(NDArray nd)
145-
=> nd._tensor.ToArray<int>()[0];
146-
147-
public static implicit operator NDArray(bool value)
148-
=> new NDArray(value);
149-
150-
public static implicit operator NDArray(float value)
151-
=> new NDArray(value);
152-
153-
public static implicit operator NDArray(double value)
154-
=> new NDArray(value);
155-
156-
public static implicit operator NDArray(byte[] value)
157-
=> new NDArray(value);
158-
159-
public static implicit operator byte[](NDArray nd)
160-
=> nd.ToByteArray();
161-
162-
public static implicit operator NDArray(int[] value)
163-
=> new NDArray(value, new Shape(value.Length));
164-
165-
public static implicit operator NDArray(float[] value)
166-
=> new NDArray(value);
167-
168-
public static implicit operator Tensor(NDArray nd)
169-
=> nd._tensor;
170-
171148
public static NDArray operator /(NDArray x, NDArray y) => throw new NotImplementedException("");
172149

173150
public override string ToString()

src/TensorFlowNET.Core/Numpy/Numpy.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,31 +84,12 @@ public static NDArray frombuffer(byte[] bytes, Type dtype)
8484
public static NDArray frombuffer(byte[] bytes, string dtype)
8585
=> throw new NotImplementedException("");
8686

87-
88-
89-
public static NDArray prod(in NDArray a, int? axis = null, Type dtype = null, bool keepdims = false)
90-
=> throw new NotImplementedException("");
91-
92-
public static NDArray prod(params int[] array)
93-
=> throw new NotImplementedException("");
94-
95-
public static NDArray multiply(in NDArray x1, in NDArray x2)
96-
=> throw new NotImplementedException("");
97-
98-
public static NDArray sum(NDArray x1)
99-
=> throw new NotImplementedException("");
100-
10187
public static NDArray squeeze(NDArray x1)
10288
=> throw new NotImplementedException("");
103-
104-
public static NDArray log(NDArray x)
105-
=> throw new NotImplementedException("");
10689

10790
public static bool allclose(NDArray a, NDArray b, double rtol = 1.0E-5, double atol = 1.0E-8,
10891
bool equal_nan = false) => throw new NotImplementedException("");
10992

110-
111-
11293
public static class random
11394
{
11495
public static NDArray permutation(int x)

src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ unsafe void InitTensor(Array array, Shape shape)
103103
fixed (void* addr = &val[0])
104104
_handle = TF_NewTensor(shape, dtype, addr, length);
105105
break;
106+
case double[,] val:
107+
fixed (void* addr = &val[0, 0])
108+
_handle = TF_NewTensor(shape, dtype, addr, length);
109+
break;
106110
default:
107111
throw new NotImplementedException("");
108112
}

src/TensorFlowNET.Core/Tensors/constant_op.cs

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ value is NDArray nd &&
159159
case EagerTensor val:
160160
return val;
161161
case NDArray val:
162-
return new EagerTensor(val, ctx.DeviceName);
162+
return (EagerTensor)val;
163163
case Shape val:
164164
return new EagerTensor(val.dims, new Shape(val.ndim));
165165
case TensorShape val:
@@ -172,49 +172,27 @@ value is NDArray nd &&
172172
return new EagerTensor(new[] { val }, Shape.Scalar);
173173
case byte val:
174174
return new EagerTensor(new[] { val }, Shape.Scalar);
175-
case byte[] val:
176-
return new EagerTensor(val, ctx.DeviceName);
177-
case byte[,] val:
178-
return new EagerTensor(val, ctx.DeviceName);
179-
case byte[,,] val:
180-
return new EagerTensor(val, ctx.DeviceName);
181175
case int val:
182176
return new EagerTensor(new[] { val }, Shape.Scalar);
183-
case int[] val:
184-
return new EagerTensor(val, new Shape(val.Length));
185-
case int[,] val:
186-
return new EagerTensor(val, new Shape(val.GetLength(0), val.GetLength(1)));
187-
case int[,,] val:
188-
return new EagerTensor(val, ctx.DeviceName);
189177
case long val:
190178
return new EagerTensor(new[] { val }, Shape.Scalar);
191-
case long[] val:
192-
return new EagerTensor(val, new Shape(val.Length));
193-
case long[,] val:
194-
return new EagerTensor(val, ctx.DeviceName);
195-
case long[,,] val:
196-
return new EagerTensor(val, ctx.DeviceName);
197179
case float val:
198180
return new EagerTensor(new[] { val }, Shape.Scalar);
199-
case float[] val:
200-
return new EagerTensor(val, ctx.DeviceName);
201-
case float[,] val:
202-
return new EagerTensor(val, ctx.DeviceName);
203-
case float[,,] val:
204-
return new EagerTensor(val, ctx.DeviceName);
205181
case double val:
206182
return new EagerTensor(new[] { val }, Shape.Scalar);
207-
case double[] val:
208-
return new EagerTensor(val, ctx.DeviceName);
209-
case double[,] val:
210-
return new EagerTensor(val, ctx.DeviceName);
211-
case double[,,] val:
212-
return new EagerTensor(val, ctx.DeviceName);
183+
case Array val:
184+
return new EagerTensor(val, GetArrayDims(val));
213185
default:
214186
throw new NotImplementedException($"convert_to_eager_tensor {value.GetType()}");
215187
}
216188
}
217189

190+
static Shape GetArrayDims(Array array)
191+
{
192+
var dims = range(array.Rank).Select(x => (long)array.GetLength(x)).ToArray();
193+
return new Shape(dims);
194+
}
195+
218196
/// <summary>
219197
/// Function to convert TensorShape to Tensor.
220198
/// </summary>

src/TensorFlowNET.Core/Variables/ResourceVariable.Operators.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public partial class ResourceVariable
3131
public static Tensor operator -(ResourceVariable x, ResourceVariable y) => x.value() - y.value();
3232

3333
public static Tensor operator *(ResourceVariable x, ResourceVariable y) => x.value() * y.value();
34+
public static Tensor operator *(ResourceVariable x, Tensor y) => x.value() * y;
3435
public static Tensor operator *(ResourceVariable x, NDArray y) => x.value() * y;
3536

3637
public static Tensor operator <(ResourceVariable x, Tensor y) => x.value() < y;

src/TensorFlowNET.Core/ops.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ public static Tensor convert_to_tensor(object value,
157157
RefVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref),
158158
ResourceVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref),
159159
TensorShape ts => constant_op.constant(ts.dims, dtype: dtype, name: name),
160-
int[] dims => constant_op.constant(dims, dtype: dtype, name: name),
161160
string str => constant_op.constant(str, dtype: tf.@string, name: name),
162161
string[] str => constant_op.constant(str, dtype: tf.@string, name: name),
163162
IEnumerable<object> objects => array_ops._autopacking_conversion_function(objects, dtype: dtype, name: name),
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using Tensorflow.NumPy;
7+
8+
namespace TensorFlowNET.UnitTest.Numpy
9+
{
10+
/// <summary>
11+
/// https://numpy.org/doc/stable/reference/generated/numpy.prod.html
12+
/// </summary>
13+
[TestClass]
14+
public class NumpyMathTest : EagerModeTestBase
15+
{
16+
[TestMethod]
17+
public void prod()
18+
{
19+
var p = np.prod(1.0, 2.0);
20+
Assert.AreEqual(p, 2.0);
21+
22+
p = np.prod(new[,] { { 1.0, 2.0 }, { 3.0, 4.0 } });
23+
Assert.AreEqual(p, 24.0);
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)