Skip to content

Commit 0acd25b

Browse files
committed
Added: fft, ifft, fft2d, ifft2d, fft3d, ifft3d
1 parent febba7b commit 0acd25b

File tree

3 files changed

+149
-24
lines changed

3 files changed

+149
-24
lines changed
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*****************************************************************************
2+
Copyright 2023 Konstantin Balashov All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
******************************************************************************/
16+
17+
using Tensorflow.Operations;
18+
19+
namespace Tensorflow
20+
{
21+
public partial class tensorflow
22+
{
23+
public SignalApi signal { get; } = new SignalApi();
24+
public class SignalApi
25+
{
26+
public Tensor fft(Tensor input, string name = null)
27+
=> gen_ops.f_f_t(input, name: name);
28+
public Tensor ifft(Tensor input, string name = null)
29+
=> gen_ops.i_f_f_t(input, name: name);
30+
public Tensor fft2d(Tensor input, string name = null)
31+
=> gen_ops.f_f_t2d(input, name: name);
32+
public Tensor ifft2d(Tensor input, string name = null)
33+
=> gen_ops.i_f_f_t2d(input, name: name);
34+
public Tensor fft3d(Tensor input, string name = null)
35+
=> gen_ops.f_f_t3d(input, name: name);
36+
public Tensor ifft3d(Tensor input, string name = null)
37+
=> gen_ops.i_f_f_t3d(input, name: name);
38+
}
39+
}
40+
}

src/TensorFlowNET.Core/Operations/gen_ops.cs

+6-24
Original file line numberDiff line numberDiff line change
@@ -10475,10 +10475,7 @@ public static Tensor extract_jpeg_shape(Tensor contents, TF_DataType? output_typ
1047510475
/// </remarks>
1047610476
public static Tensor f_f_t(Tensor input, string name = "FFT")
1047710477
{
10478-
var dict = new Dictionary<string, object>();
10479-
dict["input"] = input;
10480-
var op = tf.OpDefLib._apply_op_helper("FFT", name: name, keywords: dict);
10481-
return op.output;
10478+
return tf.Context.ExecuteOp("FFT", name, new ExecuteOpArgs(input));
1048210479
}
1048310480

1048410481
/// <summary>
@@ -10505,10 +10502,7 @@ public static Tensor f_f_t(Tensor input, string name = "FFT")
1050510502
/// </remarks>
1050610503
public static Tensor f_f_t2d(Tensor input, string name = "FFT2D")
1050710504
{
10508-
var dict = new Dictionary<string, object>();
10509-
dict["input"] = input;
10510-
var op = tf.OpDefLib._apply_op_helper("FFT2D", name: name, keywords: dict);
10511-
return op.output;
10505+
return tf.Context.ExecuteOp("FFT2D", name, new ExecuteOpArgs(input));
1051210506
}
1051310507

1051410508
/// <summary>
@@ -10535,10 +10529,7 @@ public static Tensor f_f_t2d(Tensor input, string name = "FFT2D")
1053510529
/// </remarks>
1053610530
public static Tensor f_f_t3d(Tensor input, string name = "FFT3D")
1053710531
{
10538-
var dict = new Dictionary<string, object>();
10539-
dict["input"] = input;
10540-
var op = tf.OpDefLib._apply_op_helper("FFT3D", name: name, keywords: dict);
10541-
return op.output;
10532+
return tf.Context.ExecuteOp("FFT3D", name, new ExecuteOpArgs(input));
1054210533
}
1054310534

1054410535
/// <summary>
@@ -12861,10 +12852,7 @@ public static Tensor host_const(Tensor value, TF_DataType dtype, string name = "
1286112852
/// </remarks>
1286212853
public static Tensor i_f_f_t(Tensor input, string name = "IFFT")
1286312854
{
12864-
var dict = new Dictionary<string, object>();
12865-
dict["input"] = input;
12866-
var op = tf.OpDefLib._apply_op_helper("IFFT", name: name, keywords: dict);
12867-
return op.output;
12855+
return tf.Context.ExecuteOp("IFFT", name, new ExecuteOpArgs(input));
1286812856
}
1286912857

1287012858
/// <summary>
@@ -12891,10 +12879,7 @@ public static Tensor i_f_f_t(Tensor input, string name = "IFFT")
1289112879
/// </remarks>
1289212880
public static Tensor i_f_f_t2d(Tensor input, string name = "IFFT2D")
1289312881
{
12894-
var dict = new Dictionary<string, object>();
12895-
dict["input"] = input;
12896-
var op = tf.OpDefLib._apply_op_helper("IFFT2D", name: name, keywords: dict);
12897-
return op.output;
12882+
return tf.Context.ExecuteOp("IFFT2D", name, new ExecuteOpArgs(input));
1289812883
}
1289912884

1290012885
/// <summary>
@@ -12921,10 +12906,7 @@ public static Tensor i_f_f_t2d(Tensor input, string name = "IFFT2D")
1292112906
/// </remarks>
1292212907
public static Tensor i_f_f_t3d(Tensor input, string name = "IFFT3D")
1292312908
{
12924-
var dict = new Dictionary<string, object>();
12925-
dict["input"] = input;
12926-
var op = tf.OpDefLib._apply_op_helper("IFFT3D", name: name, keywords: dict);
12927-
return op.output;
12909+
return tf.Context.ExecuteOp("IFFT3D", name, new ExecuteOpArgs(input));
1292812910
}
1292912911

1293012912
/// <summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Tensorflow.NumPy;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using Tensorflow;
7+
using static Tensorflow.Binding;
8+
using Buffer = Tensorflow.Buffer;
9+
using TensorFlowNET.Keras.UnitTest;
10+
11+
namespace TensorFlowNET.UnitTest.Basics
12+
{
13+
[TestClass]
14+
public class SignalTest : EagerModeTestBase
15+
{
16+
[TestMethod]
17+
public void fft()
18+
{
19+
double[] d_real = new double[] { 1.0, 2.0, 3.0, 4.0 };
20+
double[] d_imag = new double[] { -1.0, -3.0, 5.0, 7.0 };
21+
22+
Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_DOUBLE);
23+
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_DOUBLE);
24+
25+
Tensor t_complex = tf.complex(t_real, t_imag);
26+
27+
Tensor t_frequency_domain = tf.signal.fft(t_complex);
28+
Tensor f_time_domain = tf.signal.ifft(t_frequency_domain);
29+
30+
Tensor t_real_result = tf.math.real(f_time_domain);
31+
Tensor t_imag_result = tf.math.imag(f_time_domain);
32+
33+
NDArray n_real_result = t_real_result.numpy();
34+
NDArray n_imag_result = t_imag_result.numpy();
35+
36+
double[] d_real_result = n_real_result.ToArray<double>();
37+
double[] d_imag_result = n_imag_result.ToArray<double>();
38+
39+
Assert.IsTrue(base.Equal(d_real_result, d_real));
40+
Assert.IsTrue(base.Equal(d_imag_result, d_imag));
41+
}
42+
[TestMethod]
43+
public void fft2d()
44+
{
45+
double[] d_real = new double[] { 1.0, 2.0, 3.0, 4.0 };
46+
double[] d_imag = new double[] { -1.0, -3.0, 5.0, 7.0 };
47+
48+
Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_DOUBLE);
49+
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_DOUBLE);
50+
51+
Tensor t_complex = tf.complex(t_real, t_imag);
52+
53+
Tensor t_complex_2d = tf.reshape(t_complex,new int[] { 2, 2 });
54+
55+
Tensor t_frequency_domain_2d = tf.signal.fft2d(t_complex_2d);
56+
Tensor t_time_domain_2d = tf.signal.ifft2d(t_frequency_domain_2d);
57+
58+
Tensor t_time_domain = tf.reshape(t_time_domain_2d, new int[] { 4 });
59+
60+
Tensor t_real_result = tf.math.real(t_time_domain);
61+
Tensor t_imag_result = tf.math.imag(t_time_domain);
62+
63+
NDArray n_real_result = t_real_result.numpy();
64+
NDArray n_imag_result = t_imag_result.numpy();
65+
66+
double[] d_real_result = n_real_result.ToArray<double>();
67+
double[] d_imag_result = n_imag_result.ToArray<double>();
68+
69+
Assert.IsTrue(base.Equal(d_real_result, d_real));
70+
Assert.IsTrue(base.Equal(d_imag_result, d_imag));
71+
}
72+
[TestMethod]
73+
public void fft3d()
74+
{
75+
double[] d_real = new double[] { 1.0, 2.0, 3.0, 4.0, -3.0, -2.0, -1.0, -4.0 };
76+
double[] d_imag = new double[] { -1.0, -3.0, 5.0, 7.0, 6.0, 4.0, 2.0, 0.0};
77+
78+
Tensor t_real = tf.constant(d_real, dtype: TF_DataType.TF_DOUBLE);
79+
Tensor t_imag = tf.constant(d_imag, dtype: TF_DataType.TF_DOUBLE);
80+
81+
Tensor t_complex = tf.complex(t_real, t_imag);
82+
83+
Tensor t_complex_3d = tf.reshape(t_complex, new int[] { 2, 2, 2 });
84+
85+
Tensor t_frequency_domain_3d = tf.signal.fft2d(t_complex_3d);
86+
Tensor t_time_domain_3d = tf.signal.ifft2d(t_frequency_domain_3d);
87+
88+
Tensor t_time_domain = tf.reshape(t_time_domain_3d, new int[] { 8 });
89+
90+
Tensor t_real_result = tf.math.real(t_time_domain);
91+
Tensor t_imag_result = tf.math.imag(t_time_domain);
92+
93+
NDArray n_real_result = t_real_result.numpy();
94+
NDArray n_imag_result = t_imag_result.numpy();
95+
96+
double[] d_real_result = n_real_result.ToArray<double>();
97+
double[] d_imag_result = n_imag_result.ToArray<double>();
98+
99+
Assert.IsTrue(base.Equal(d_real_result, d_real));
100+
Assert.IsTrue(base.Equal(d_imag_result, d_imag));
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)