0
$\begingroup$

I was trying to use the torch.fft to compute derivatives. The issue is that even for a simple example ($f = \sin(x)$), I have weird oscillations on the boundaries.

Is there an issue in the following code, or is there a problem with torch.fft (or, more probably, how I use it)?

Thanks

import torch
import torch.fft

# Define the number of sample points and the domain
n = 1024
x = torch.linspace(0, 2 * torch.pi, n)
# Define the function f(x) = sin(x)
f_x = torch.sin(x)
# Compute the FFT of the function
F_k = torch.fft.fft(f_x)
# Define the frequencies
k = torch.fft.fftfreq(n, d=(2 * torch.pi / n))
# Compute the  derivative
derivative_fft = 1j * 2 * torch.pi * k * F_k
# Compute the inverse FFT to get the derivative in the time domain
df_x = torch.fft.ifft(derivative_fft).real
# The real part is taken as the result since the input is real-valued
# Print the original function and its derivative
import matplotlib.pyplot as plt

plt.plot(x, f_x, label='f(x) = sin(x)')
plt.plot(x, df_x, label="f'(x) = cos(x)", linestyle='dashed')
plt.legend()
plt.xlabel('x')
plt.ylabel('Value')
plt.title('Function and its Derivative using FFT')
plt.grid(True)
plt.show()

derivative computed using torch.fft

EDIT: I should be more precise. When I use the fft from numpy I see no oscillation:

import numpy as np
import matplotlib.pyplot as plt

# Define the function to be differentiated
def f(x):
    return np.sin(x)

# Number of sample points
N = 1024
# Sampling interval
L = 2 * np.pi
x = np.linspace(0, L, N, endpoint=False)
y = f(x)

# FFT of the function
y_fft = np.fft.fft(y)

# Frequency components
k = np.fft.fftfreq(N, L / N) * 2 * np.pi

# Differentiation in the frequency domain (multiply by i*k)
y_fft_derivative = 1j * k * y_fft

# Inverse FFT to get back to the spatial domain
y_derivative = np.fft.ifft(y_fft_derivative)

# The imaginary part should be very close to zero
y_derivative_real = np.real(y_derivative)

# Exact derivative of sin(x)
exact_derivative = np.cos(x)

# Plot the results
plt.plot(x, y_derivative_real, label='FFT Derivative')
plt.plot(x, exact_derivative, label='Exact Derivative', linestyle='--')
plt.legend()
plt.xlabel('x')
plt.ylabel('Derivative')
plt.title('Derivative of sin(x) using FFT')
plt.show()

fft numpy

$\endgroup$
1

1 Answer 1

2
$\begingroup$

Replace

x = torch.linspace(0, 2 * torch.pi, n)

with

dx = 2 * torch.pi / n
x = torch.linspace(0, 2 * torch.pi - dx, n)

I think the code needs no further explanation.

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.