import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
# Define constants
timesteps = 50
future_steps = 20
features = 5 # Number of features
time = np.linspace(0, 10, timesteps) # Time vector
time_extended = np.linspace(0, 10 + (future_steps * (10 / timesteps)), timesteps + future_steps)
# Generate synthetic periodic data
synthetic_data = np.zeros((timesteps, features))
synthetic_data[:, 0] = np.sin(2 * np.pi * 1.0 * time) + 0.5 * np.cos(2 * np.pi * 3.0 * time)
synthetic_data[:, 1] = np.sin(2 * np.pi * 0.5 * time) + np.cos(2 * np.pi * 2.5 * time)
synthetic_data[:, 2] = 1.5 * np.sin(2 * np.pi * 2.0 * time) - 0.3 * np.cos(2 * np.pi * 1.0 * time)
synthetic_data[:, 3] = np.sin(2 * np.pi * 1.5 * time) + 0.2 * np.cos(2 * np.pi * 4.0 * time)
synthetic_data[:, 4] = 0.7 * np.sin(2 * np.pi * 2.8 * time) - 0.4 * np.cos(2 * np.pi * 1.8 * time)
# Compute FFT using NumPy
fft_output_np = np.fft.fft(synthetic_data, axis=0)
frequencies_np = np.fft.fftfreq(timesteps)
amplitudes_np = np.abs(fft_output_np) / timesteps
phases_np = np.angle(fft_output_np)
# Compute FFT using TensorFlow
fft_output_tf = tf.signal.fft(synthetic_data)
amplitudes_tf = tf.abs(fft_output_tf) / tf.cast(timesteps, tf.float32)
phases_tf = tf.math.angle(fft_output_tf)
# Convert TensorFlow tensors to NumPy arrays
fft_output_tf_np = fft_output_tf.numpy()
amplitudes_tf_np = amplitudes_tf.numpy()
phases_tf_np = phases_tf.numpy()
# --------------------------------------------
# ✅ Direct IFFT Reconstruction (Original FFT)
# --------------------------------------------
ifft_reconstructed_np = np.fft.ifft(fft_output_np, axis=0).real
ifft_reconstructed_tf = tf.signal.ifft(fft_output_tf).numpy().real
# --------------------------------------------
# ✅ IFFT Reconstruction from Amplitudes & Phases
# --------------------------------------------
# NumPy Reconstruction
complex_reconstructed_np = amplitudes_np * np.exp(1j * phases_np) * timesteps # Recreate FFT values
ifft_reconstructed_from_ap_np = np.fft.ifft(complex_reconstructed_np, axis=0).real # IFFT
# TensorFlow Reconstruction
complex_reconstructed_tf = tf.complex(amplitudes_tf * tf.cos(phases_tf), amplitudes_tf * tf.sin(phases_tf)) * tf.cast(timesteps, tf.complex64)
ifft_reconstructed_from_ap_tf = tf.signal.ifft(complex_reconstructed_tf).numpy().real
complex_reconstructed_tf_np = complex_reconstructed_tf.numpy() # Convert to NumPy for printing
# Select a feature for detailed debugging
feature_idx = 0
# ✅ Print Debugging Information
print("\n🔹 Debugging Fourier Transform Components for Feature", feature_idx)
# Print Complex Numbers (Real & Imaginary)
print("\n--- COMPLEX NUMBERS (Reconstructed from Amplitudes & Phases) ---")
print("TensorFlow FFT Output:\n", fft_output_tf[:, feature_idx])
print("NumPy FFT Output:\n", fft_output_np[:, feature_idx])
# --------------------------------------------
# ✅ Predict Future Values using Fourier Expansion
# --------------------------------------------
future_predictions_np = np.zeros((future_steps, features))
future_predictions_tf = np.zeros((future_steps, features))
for t in range(future_steps):
t_future = timesteps + t # Time index for future steps
# NumPy: Predict future values using Fourier series expansion
future_predictions_np[t] = np.sum(amplitudes_np * np.cos(2 * np.pi * frequencies_np[:, None] * t_future + phases_np), axis=0)
# TensorFlow: Predict future values using Fourier series expansion
future_predictions_tf[t] = np.sum(amplitudes_tf_np * np.cos(2 * np.pi * frequencies_np[:, None] * t_future + phases_tf_np), axis=0)
# --------------------------------------------
# ✅ Extend Data for Plotting
# --------------------------------------------
full_signal_np = np.concatenate((ifft_reconstructed_np, future_predictions_np), axis=0)
full_signal_tf = np.concatenate((ifft_reconstructed_tf, future_predictions_tf), axis=0)
# --------------------------------------------
# ✅ Plotting: Future Predictions from Different Reconstructions
# --------------------------------------------
plt.figure(figsize=(12, 8))
for i in range(features):
plt.subplot(features, 1, i + 1)
plt.plot(time_extended, full_signal_np[:, i], label='Direct IFFT + Prediction (NumPy)', linestyle='solid', linewidth=2, alpha=0.7, color='blue')
plt.plot(time_extended, full_signal_tf[:, i], label='Direct IFFT + Prediction (TensorFlow)', linestyle='dashed', linewidth=2, alpha=0.7, color='green')
plt.axvline(x=time[-1], color='black', linestyle='--', label="Prediction Start")
plt.legend()
plt.title(f"Prediction Comparison (Feature {i+1})")
plt.tight_layout()
plt.show()
--- COMPLEX NUMBERS (Reconstructed from Amplitudes & Phases) ---
TensorFlow FFT Output:
tf.Tensor(
[ 1. +0.j 1.8956809 +0.j 1.2586026 +0.j -0.40646017+0.j
0.9350877 +0.j -1.1103796 +0.j 0.95443094+0.j -1.3580153 +0.j
0.7564049 +0.j -4.5968194 +0.j 1.9695193 +0.j 2.206369 +0.j
0.08039129+0.j 1.4168235 +0.j -1.279043 +0.j 0.13616711+0.j
0.5050415 +0.j -1.5471683 +0.j 1.381841 +0.j -5.525199 +0.j
3.2019842 +0.j 1.9095042 +0.j -0.61422163+0.j 2.509771 +0.j
-2.2938673 +0.j 0.8726954 +0.j -0.800195 +0.j 0.24049258+0.j
-1.170131 +0.j -2.8509908 +0.j 2.538548 +0.j 1.1680496 +0.j
0.6346374 +0.j 0.6699722 +0.j -0.62059027+0.j 0.39178047+0.j
-1.8831189 +0.j 2.1379056 +0.j -4.2216344 +0.j 0.34866822+0.j
1.6591074 +0.j 1.0568695 +0.j 0.50590456+0.j 0.43404764+0.j
-0.5220758 +0.j 0.55441445+0.j -1.6021513 +0.j 1.195328 +0.j
-4.12398 +0.j 1. +0.j], shape=(50,), dtype=complex64)
NumPy FFT Output:
[ 5.00000000e-01+0.00000000e+00j 5.05609841e-01-5.34290797e-02j
5.23097541e-01-1.10961382e-01j 5.54643041e-01-1.77614989e-01j
6.04694370e-01-2.60679983e-01j 6.81793083e-01-3.72364007e-01j
8.03155178e-01-5.36032682e-01j 1.00793942e+00-8.04020615e-01j
1.40671379e+00-1.32388205e+00j 2.47744792e+00-2.73489136e+00j
1.40631845e+01-1.82238953e+01j -3.45850242e+00+5.30263973e+00j
-1.45817369e+00+2.69066818e+00j -8.76036084e-01+2.00643206e+00j
-5.82708758e-01+1.75124914e+00j -3.84581501e-01+1.69374226e+00j
-2.08832880e-01+1.79764496e+00j 8.58395137e-03+2.14129348e+00j
4.36072145e-01+3.13644006e+00j 2.85720849e+00+9.60556002e+00j
-2.56086256e+00-5.18343952e+00j -1.24899273e+00-1.64805604e+00j
-9.45467631e-01-8.17719794e-01j -8.19803359e-01-4.33572383e-01j
-7.63022000e-01-1.92211030e-01j -7.46319396e-01-5.55111512e-16j
-7.63022000e-01+1.92211030e-01j -8.19803359e-01+4.33572383e-01j
-9.45467631e-01+8.17719794e-01j -1.24899273e+00+1.64805604e+00j
-2.56086256e+00+5.18343952e+00j 2.85720849e+00-9.60556002e+00j
4.36072145e-01-3.13644006e+00j 8.58395137e-03-2.14129348e+00j
-2.08832880e-01-1.79764496e+00j -3.84581501e-01-1.69374226e+00j
-5.82708758e-01-1.75124914e+00j -8.76036084e-01-2.00643206e+00j
-1.45817369e+00-2.69066818e+00j -3.45850242e+00-5.30263973e+00j
1.40631845e+01+1.82238953e+01j 2.47744792e+00+2.73489136e+00j
1.40671379e+00+1.32388205e+00j 1.00793942e+00+8.04020615e-01j
8.03155178e-01+5.36032682e-01j 6.81793083e-01+3.72364007e-01j
6.04694370e-01+2.60679983e-01j 5.54643041e-01+1.77614989e-01j
5.23097541e-01+1.10961382e-01j 5.05609841e-01+5.34290797e-02j]
准确性在这里无关紧要。我非常了解Numpy和Tensorflow具有不同的精度。 Numpy用复杂的128和张量为复杂的64计算。但是,这应该仅产生与价值的微小未对准,但是这些截然不同。 这些是Numpy和TensorFlow的计算未来值的输出:
numpy和Tensorflow未来步骤值的差异值
关键问题是,默认情况下,TensorFlow的FFT函数在输入张量的最内部(最后一个)维度上运行,而在Numpy代码中,您沿时间轴明确计算了FFT(AXIS 0)。随着您的合成数据形状为(时间段,功能),即(50,5) - Numpy的FFT在每个功能的50个样本上运行(随时间捕获定期行为),而tf.signal.fft则在每行5个样本上运行(跨特征)。此不匹配导致每行的TensorFlow返回FFT输出,几乎为零的假想组件,这就是为什么即使通过IFFT进行重建仍然有效的值,您也会看到诸如“ 1.0+0.J”之类的值。
要解决此问题,您需要确保TensorFlow沿着与Numpy(即时轴)相同的轴计算FFT。做到这一点的一种方法是转置数据,以使时间维成为最内在的维度,如以下示例:
# cast to complex and transpose so that time axis is last
synthetic_data_tf = tf.cast(tf.transpose(synthetic_data), tf.complex64)
# compute FFT along the time axis (now the last dimension)
fft_output_tf = tf.signal.fft(synthetic_data_tf)
# transpose back if needed for further processing
fft_output_tf = tf.transpose(fft_output_tf)