@@ -14,6 +14,7 @@ | |||||
limitations under the License. | limitations under the License. | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
using Tensorflow.NumPy; | |||||
using Tensorflow.Operations; | using Tensorflow.Operations; | ||||
namespace Tensorflow | namespace Tensorflow | ||||
@@ -42,7 +43,6 @@ namespace Tensorflow | |||||
public Tensor multiply(Tensor x, Tensor y, string name = null) | public Tensor multiply(Tensor x, Tensor y, string name = null) | ||||
=> math_ops.multiply(x, y, name: name); | => math_ops.multiply(x, y, name: name); | ||||
public Tensor divide_no_nan(Tensor a, Tensor b, string name = null) | public Tensor divide_no_nan(Tensor a, Tensor b, string name = null) | ||||
=> math_ops.div_no_nan(a, b); | => math_ops.div_no_nan(a, b); | ||||
@@ -452,7 +452,18 @@ namespace Tensorflow | |||||
/// <returns></returns> | /// <returns></returns> | ||||
public Tensor multiply<Tx, Ty>(Tx x, Ty y, string name = null) | public Tensor multiply<Tx, Ty>(Tx x, Ty y, string name = null) | ||||
=> gen_math_ops.mul(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name: name); | => gen_math_ops.mul(ops.convert_to_tensor(x), ops.convert_to_tensor(y), name: name); | ||||
/// <summary> | |||||
/// return scalar product | |||||
/// </summary> | |||||
/// <typeparam name="Tx"></typeparam> | |||||
/// <typeparam name="Ty"></typeparam> | |||||
/// <param name="x"></param> | |||||
/// <param name="y"></param> | |||||
/// <param name="axes"></param> | |||||
/// <param name="name"></param> | |||||
/// <returns></returns> | |||||
public Tensor dot_prod<Tx, Ty>(Tx x, Ty y, NDArray axes, string name = null) | |||||
=> math_ops.tensordot(convert_to_tensor(x), convert_to_tensor(y), axes, name: name); | |||||
public Tensor negative(Tensor x, string name = null) | public Tensor negative(Tensor x, string name = null) | ||||
=> gen_math_ops.neg(x, name); | => gen_math_ops.neg(x, name); | ||||
@@ -486,7 +486,28 @@ namespace Tensorflow | |||||
throw new NotImplementedException(""); | throw new NotImplementedException(""); | ||||
} | } | ||||
} | } | ||||
public static NDArray GetFlattenArray(NDArray x) | |||||
{ | |||||
switch (x.GetDataType()) | |||||
{ | |||||
case TF_DataType.TF_FLOAT: | |||||
x = x.ToArray<float>(); | |||||
break; | |||||
case TF_DataType.TF_DOUBLE: | |||||
x = x.ToArray<double>(); | |||||
break; | |||||
case TF_DataType.TF_INT16: | |||||
case TF_DataType.TF_INT32: | |||||
x = x.ToArray<int>(); | |||||
break; | |||||
case TF_DataType.TF_INT64: | |||||
x = x.ToArray<long>(); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
return x; | |||||
} | |||||
public static TF_DataType GetDataType(this object data) | public static TF_DataType GetDataType(this object data) | ||||
{ | { | ||||
var type = data.GetType(); | var type = data.GetType(); | ||||
@@ -49,9 +49,30 @@ namespace Tensorflow.NumPy | |||||
[AutoNumPy] | [AutoNumPy] | ||||
public static NDArray prod<T>(params T[] array) where T : unmanaged | public static NDArray prod<T>(params T[] array) where T : unmanaged | ||||
=> new NDArray(tf.reduce_prod(new NDArray(array))); | => new NDArray(tf.reduce_prod(new NDArray(array))); | ||||
[AutoNumPy] | |||||
public static NDArray dot(NDArray x1, NDArray x2, NDArray? axes = null, string? name = null) | |||||
{ | |||||
//if axes mentioned | |||||
if (axes != null) | |||||
{ | |||||
return new NDArray(tf.dot_prod(x1, x2, axes, name)); | |||||
} | |||||
if (x1.shape.ndim > 1) | |||||
{ | |||||
x1 = GetFlattenArray(x1); | |||||
} | |||||
if (x2.shape.ndim > 1) | |||||
{ | |||||
x2 = GetFlattenArray(x2); | |||||
} | |||||
//if axes not mentioned, default 0,0 | |||||
return new NDArray(tf.dot_prod(x1, x2, axes: new int[] { 0, 0 }, name)); | |||||
} | |||||
[AutoNumPy] | [AutoNumPy] | ||||
public static NDArray power(NDArray x, NDArray y) => new NDArray(tf.pow(x, y)); | public static NDArray power(NDArray x, NDArray y) => new NDArray(tf.pow(x, y)); | ||||
[AutoNumPy] | |||||
public static NDArray square(NDArray x) => new NDArray(tf.square(x)); | |||||
[AutoNumPy] | [AutoNumPy] | ||||
public static NDArray sin(NDArray x) => new NDArray(math_ops.sin(x)); | public static NDArray sin(NDArray x) => new NDArray(math_ops.sin(x)); | ||||
@@ -65,7 +65,34 @@ namespace TensorFlowNET.UnitTest.NumPy | |||||
var y = np.power(x, 3); | var y = np.power(x, 3); | ||||
Assert.AreEqual(y, new[] { 0, 1, 8, 27, 64, 125 }); | Assert.AreEqual(y, new[] { 0, 1, 8, 27, 64, 125 }); | ||||
} | } | ||||
[TestMethod] | |||||
[TestMethod] | |||||
public void square() | |||||
{ | |||||
var x = np.arange(6); | |||||
var y = np.square(x); | |||||
Assert.AreEqual(y, new[] { 0, 1, 4, 9, 16, 25 }); | |||||
} | |||||
[TestMethod] | |||||
public void dotproduct() | |||||
{ | |||||
var x1 = new NDArray(new[] { 1, 2, 3 }); | |||||
var x2 = new NDArray(new[] { 4, 5, 6 }); | |||||
double result1 = np.dot(x1, x2); | |||||
NDArray y1 = new float[,] { | |||||
{ 1.0f, 2.0f, 3.0f }, | |||||
{ 4.0f, 5.1f,6.0f }, | |||||
{ 4.0f, 5.1f,6.0f } | |||||
}; | |||||
NDArray y2 = new float[,] { | |||||
{ 3.0f, 2.0f, 1.0f }, | |||||
{ 6.0f, 5.1f, 4.0f }, | |||||
{ 6.0f, 5.1f, 4.0f } | |||||
}; | |||||
double result2 = np.dot(y1, y2); | |||||
Assert.AreEqual(result1, 32); | |||||
Assert.AreEqual(Math.Round(result2, 2), 158.02); | |||||
} | |||||
[TestMethod] | |||||
public void maximum() | public void maximum() | ||||
{ | { | ||||
var x1 = new NDArray(new[,] { { 1, 2, 3 }, { 4, 5.1, 6 } }); | var x1 = new NDArray(new[,] { { 1, 2, 3 }, { 4, 5.1, 6 } }); | ||||