Browse Source

Added: complex, real, imag, angle

tags/v0.100.5-BERT-load
BalashovK 2 years ago
parent
commit
f9409ed8f3
6 changed files with 184 additions and 39 deletions
  1. +26
    -0
      src/TensorFlowNET.Core/APIs/tf.complex.cs
  2. +12
    -2
      src/TensorFlowNET.Core/APIs/tf.math.cs
  3. +8
    -35
      src/TensorFlowNET.Core/Operations/gen_ops.cs
  4. +4
    -2
      src/TensorFlowNET.Core/Operations/math_ops.cs
  5. +133
    -0
      test/TensorFlowNET.Graph.UnitTest/ComplexTest.cs
  6. +1
    -0
      test/TensorFlowNET.Graph.UnitTest/TensorFlowNET.Graph.UnitTest.csproj

+ 26
- 0
src/TensorFlowNET.Core/APIs/tf.complex.cs View File

@@ -0,0 +1,26 @@
/*****************************************************************************
Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************/

using Tensorflow.Operations;

namespace Tensorflow
{
public partial class tensorflow
{
public Tensor complex(Tensor real, Tensor imag, Tensorflow.TF_DataType? dtype = null,
string name = null) => gen_ops.complex(real, imag, dtype, name);
}
}

+ 12
- 2
src/TensorFlowNET.Core/APIs/tf.math.cs View File

@@ -57,7 +57,7 @@ namespace Tensorflow

public Tensor tanh(Tensor x, string name = null)
=> math_ops.tanh(x, name: name);
/// <summary>
/// Finds values and indices of the `k` largest entries for the last dimension.
/// </summary>
@@ -93,6 +93,16 @@ namespace Tensorflow
bool binary_output = false)
=> math_ops.bincount(arr, weights: weights, minlength: minlength, maxlength: maxlength,
dtype: dtype, name: name, axis: axis, binary_output: binary_output);

public Tensor real(Tensor x, string name = null)
=> gen_ops.real(x, x.dtype.real_dtype(), name);
public Tensor imag(Tensor x, string name = null)
=> gen_ops.imag(x, x.dtype.real_dtype(), name);

public Tensor conj(Tensor x, string name = null)
=> gen_ops.conj(x, name);
public Tensor angle(Tensor x, string name = null)
=> gen_ops.angle(x, x.dtype.real_dtype(), name);
}

public Tensor abs(Tensor x, string name = null)
@@ -537,7 +547,7 @@ namespace Tensorflow
public Tensor reduce_sum(Tensor input, Axis? axis = null, Axis? reduction_indices = null,
bool keepdims = false, string name = null)
{
if(keepdims)
if (keepdims)
return math_ops.reduce_sum(input, axis: constant_op.constant(axis ?? reduction_indices), keepdims: keepdims, name: name);
else
return math_ops.reduce_sum(input, axis: constant_op.constant(axis ?? reduction_indices));


+ 8
- 35
src/TensorFlowNET.Core/Operations/gen_ops.cs View File

@@ -730,12 +730,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor angle(Tensor input, TF_DataType? Tout = null, string name = "Angle")
{
var dict = new Dictionary<string, object>();
dict["input"] = input;
if (Tout.HasValue)
dict["Tout"] = Tout.Value;
var op = tf.OpDefLib._apply_op_helper("Angle", name: name, keywords: dict);
return op.output;
return tf.Context.ExecuteOp("Angle", name, new ExecuteOpArgs(new object[] { input }));
}

/// <summary>
@@ -4978,15 +4973,11 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor complex(Tensor real, Tensor imag, TF_DataType? Tout = null, string name = "Complex")
{
var dict = new Dictionary<string, object>();
dict["real"] = real;
dict["imag"] = imag;
if (Tout.HasValue)
dict["Tout"] = Tout.Value;
var op = tf.OpDefLib._apply_op_helper("Complex", name: name, keywords: dict);
return op.output;
return tf.Context.ExecuteOp("Complex", name, new ExecuteOpArgs(new object[] { real, imag })); // sorry, cannot pass Tout, so it only works with complex64. complex128 is not supported yet
}



/// <summary>
/// Computes the complex absolute value of a tensor.
/// </summary>
@@ -5008,12 +4999,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor complex_abs(Tensor x, TF_DataType? Tout = null, string name = "ComplexAbs")
{
var dict = new Dictionary<string, object>();
dict["x"] = x;
if (Tout.HasValue)
dict["Tout"] = Tout.Value;
var op = tf.OpDefLib._apply_op_helper("ComplexAbs", name: name, keywords: dict);
return op.output;
return tf.Context.ExecuteOp("ComplexAbs", name, new ExecuteOpArgs(new object[] { x }));
}

/// <summary>
@@ -5313,10 +5299,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor conj(Tensor input, string name = "Conj")
{
var dict = new Dictionary<string, object>();
dict["input"] = input;
var op = tf.OpDefLib._apply_op_helper("Conj", name: name, keywords: dict);
return op.output;
return tf.Context.ExecuteOp("Conj", name, new ExecuteOpArgs(new object[] { input }));
}

/// <summary>
@@ -13327,12 +13310,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor imag(Tensor input, TF_DataType? Tout = null, string name = "Imag")
{
var dict = new Dictionary<string, object>();
dict["input"] = input;
if (Tout.HasValue)
dict["Tout"] = Tout.Value;
var op = tf.OpDefLib._apply_op_helper("Imag", name: name, keywords: dict);
return op.output;
return tf.Context.ExecuteOp("Imag", name, new ExecuteOpArgs(new object[] { input }));
}

/// <summary>
@@ -23865,12 +23843,7 @@ namespace Tensorflow.Operations
/// </remarks>
public static Tensor real(Tensor input, TF_DataType? Tout = null, string name = "Real")
{
var dict = new Dictionary<string, object>();
dict["input"] = input;
if (Tout.HasValue)
dict["Tout"] = Tout.Value;
var op = tf.OpDefLib._apply_op_helper("Real", name: name, keywords: dict);
return op.output;
return tf.Context.ExecuteOp("Real", name, new ExecuteOpArgs(new object[] {input}));
}

/// <summary>


+ 4
- 2
src/TensorFlowNET.Core/Operations/math_ops.cs View File

@@ -20,6 +20,7 @@ using System.Collections.Generic;
using System.Linq;
using Tensorflow.Framework;
using static Tensorflow.Binding;
using Tensorflow.Operations;

namespace Tensorflow
{
@@ -35,8 +36,9 @@ namespace Tensorflow
name = scope;
x = ops.convert_to_tensor(x, name: "x");
if (x.dtype.is_complex())
throw new NotImplementedException("math_ops.abs for dtype.is_complex");
//return gen_math_ops.complex_abs(x, Tout: x.dtype.real_dtype, name: name);
{
return gen_ops.complex_abs(x, Tout: x.dtype.real_dtype(), name: name);
}
return gen_math_ops._abs(x, name: name);
});
}


+ 133
- 0
test/TensorFlowNET.Graph.UnitTest/ComplexTest.cs View File

@@ -0,0 +1,133 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Tensorflow.NumPy;
using System;
using System.Collections.Generic;
using System.Linq;
using Tensorflow;
using static Tensorflow.Binding;
using Buffer = Tensorflow.Buffer;
using TensorFlowNET.Keras.UnitTest;

namespace TensorFlowNET.UnitTest.Basics
{
[TestClass]
public class ComplexTest : EagerModeTestBase
{
[Ignore("Not working")]
[TestMethod]
public void complex128_basic()
{
double[] d_real = new double[] { 1.0, 2.0, 3.0, 4.0 };
double[] d_imag = new double[] { -1.0, -3.0, 5.0, 7.0 };

Tensor t_real = tf.constant(d_real, dtype:TF_DataType.TF_DOUBLE);
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_DOUBLE);

Tensor t_complex = tf.complex(t_real, t_imag, TF_DataType.TF_COMPLEX128);

Tensor t_real_result = tf.math.real(t_complex);
Tensor t_imag_result = tf.math.imag(t_complex);

NDArray n_real_result = t_real_result.numpy();
NDArray n_imag_result = t_imag_result.numpy();

double[] d_real_result =n_real_result.ToArray<double>();
double[] d_imag_result = n_imag_result.ToArray<double>();

Assert.AreEqual(d_real_result, d_real);
Assert.AreEqual(d_imag_result, d_imag);
}
[TestMethod]
public void complex64_basic()
{
tf.init_scope();
float[] d_real = new float[] { 1.0f, 2.0f, 3.0f, 4.0f };
float[] d_imag = new float[] { -1.0f, -3.0f, 5.0f, 7.0f };

Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_FLOAT);
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_FLOAT);

Tensor t_complex = tf.complex(t_real, t_imag, TF_DataType.TF_COMPLEX64);

Tensor t_real_result = tf.math.real(t_complex);
Tensor t_imag_result = tf.math.imag(t_complex);

// Convert the EagerTensors to NumPy arrays directly
float[] d_real_result = t_real_result.numpy().ToArray<float>();
float[] d_imag_result = t_imag_result.numpy().ToArray<float>();

Assert.IsTrue(base.Equal(d_real_result, d_real));
Assert.IsTrue(base.Equal(d_imag_result, d_imag));
}
[TestMethod]
public void complex64_abs()
{
tf.enable_eager_execution();
float[] d_real = new float[] { -3.0f, -5.0f, 8.0f, 7.0f };
float[] d_imag = new float[] { -4.0f, 12.0f, -15.0f, 24.0f };

float[] d_abs = new float[] { 5.0f, 13.0f, 17.0f, 25.0f };

Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_FLOAT);
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_FLOAT);

Tensor t_complex = tf.complex(t_real, t_imag, TF_DataType.TF_COMPLEX64);

Tensor t_abs_result = tf.abs(t_complex);

NDArray n_abs_result = t_abs_result.numpy();

float[] d_abs_result = n_abs_result.ToArray<float>();
Assert.IsTrue(base.Equal(d_abs_result, d_abs));

}
[TestMethod]
public void complex64_conj()
{
float[] d_real = new float[] { -3.0f, -5.0f, 8.0f, 7.0f };
float[] d_imag = new float[] { -4.0f, 12.0f, -15.0f, 24.0f };

float[] d_real_expected = new float[] { -3.0f, -5.0f, 8.0f, 7.0f };
float[] d_imag_expected = new float[] { 4.0f, -12.0f, 15.0f, -24.0f };

Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_FLOAT);
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_FLOAT);

Tensor t_complex = tf.complex(t_real, t_imag, TF_DataType.TF_COMPLEX64);

Tensor t_result = tf.math.conj(t_complex);

NDArray n_real_result = tf.math.real(t_result).numpy();
NDArray n_imag_result = tf.math.imag(t_result).numpy();

float[] d_real_result = n_real_result.ToArray<float>();
float[] d_imag_result = n_imag_result.ToArray<float>();

Assert.IsTrue(base.Equal(d_real_result, d_real_expected));
Assert.IsTrue(base.Equal(d_imag_result, d_imag_expected));

}
[TestMethod]
public void complex64_angle()
{
float[] d_real = new float[] { 0.0f, 1.0f, -1.0f, 0.0f };
float[] d_imag = new float[] { 1.0f, 0.0f, -2.0f, -3.0f };

float[] d_expected = new float[] { 1.5707964f, 0f, -2.0344439f, -1.5707964f };
Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_FLOAT);
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_FLOAT);

Tensor t_complex = tf.complex(t_real, t_imag, TF_DataType.TF_COMPLEX64);

Tensor t_result = tf.math.angle(t_complex);

NDArray n_result = t_result.numpy();

float[] d_result = n_result.ToArray<float>();

Assert.IsTrue(base.Equal(d_result, d_expected));
}
}
}

+ 1
- 0
test/TensorFlowNET.Graph.UnitTest/TensorFlowNET.Graph.UnitTest.csproj View File

@@ -36,6 +36,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\TensorFlowNET.Core\Tensorflow.Binding.csproj" />
<ProjectReference Include="..\TensorFlowNET.Keras.UnitTest\Tensorflow.Keras.UnitTest.csproj" />
</ItemGroup>

</Project>

Loading…
Cancel
Save