Skip to main content
added 44 characters in body
Source Link
mins
  • 473
  • 3
  • 11

Now if the angles for the original signal are subtracted from the angles for the shifted signal, the result is an arithmetical progression with a common difference $p_d$.:

enter image description here

Now if the angles for the original signal are subtracted from the angles for the shifted signal, the result is an arithmetical progression with a common difference $p_d$.

Now if the angles for the original signal are subtracted from the angles for the shifted signal, the result is an arithmetical progression with a common difference $p_d$:

enter image description here

added 51 characters in body
Source Link
mins
  • 473
  • 3
  • 11

(I'm using the general nameterm DFT, the transform implemented by FFT algorithm.)

To get the DFT of a shifted signal the DFT of the unshifted signal $X[k]$ is multiplied by $e^{-j\frac{2\pi k}{N}n_{d}}$.

$$n_d = -\frac {N p_d} {2 \pi}$$$$n_d = -\frac {N} {2 \pi}p_d$$

import numpy as np import scipy.fft as sf import matplotlib.pyplot as plt   # Generate a signal delayed or not def signal_gen(length, delay=0, aliasing=False): indices = np.arange(-delay, -delay+length) if aliasing: indices = indices % length values = np.linspace(1, 0, length) ** 2 + 0.2 xn = np.where((indices<0) | (indices>=length), 0, values[indices]) return xn # Plot signal def plot(xn, Xk, title='Signal', unwrap=False): # Plot signal fig, axes = plt.subplots(ncols=3, squeeze=True, figsize=(8, 2.5), layout='constrained') ax = axes[0] ax.set_title(title) ax.stem(xn) # Plot spectrumDFT magnitude ax = axes[1] ax.set_title('DFT magnitude') ax.stem(abs(Xk)) # Plot reconstructedDFT spectrumangle ax = axes[2] ax.set_title('DFT angle') angles = np.angle(Xk) if unwrap: angles = np.unwrap(angles) ax.stem(angles) N = 9 # number of samples to create nd = 4 # time-delay in samples # Original and time-shifted signals xn = signal_gen(N, 0) xn_s = signal_gen(N, nd, aliasing=True) # Plot Xk, Xk_s = [sf.fft(signal) for signal in [xn, xn_s]] plot(xn, Xk, title='Unshifted signal') plot(xn_s, Xk_s, title='Time-shifted signal') # Phase differences between DFT of shifted and unshifted signals phase_wrapped = np.angle(Xk_s) - np.angle(Xk) phase = np.unwrap(phase_wrapped) # Print wrapped and unwrapped phase differences and increments print(np.array2string(phase_wrapped, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(phase, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(np.diff(phase), formatter={'float_kind': lambda x: "%.2f" % x})) # Compute time-delay pd = phase[1]-phase[0] nd2 = -N * pd / (2*np.pi) print(f'nd = {nd2:.2f}') 

When we know the phase increment $pd=2.79$, we can determine theThe time-delay as a number of samples is determined from the phase increment $p_d=-2.79$:

(I'm using the general name DFT, the transform implemented by FFT algorithm.)

To get the DFT of a shifted signal the DFT of the unshifted signal is multiplied by $e^{-j\frac{2\pi k}{N}n_{d}}$.

$$n_d = -\frac {N p_d} {2 \pi}$$

import numpy as np import scipy.fft as sf import matplotlib.pyplot as plt def signal_gen(length, delay=0, aliasing=False): indices = np.arange(-delay, -delay+length) if aliasing: indices = indices % length values = np.linspace(1, 0, length) ** 2 + 0.2 xn = np.where((indices<0) | (indices>=length), 0, values[indices]) return xn def plot(xn, Xk, title='Signal', unwrap=False): # Plot signal fig, axes = plt.subplots(ncols=3, squeeze=True, figsize=(8, 2.5), layout='constrained') ax = axes[0] ax.set_title(title) ax.stem(xn) # Plot spectrum ax = axes[1] ax.set_title('DFT magnitude') ax.stem(abs(Xk)) # Plot reconstructed spectrum ax = axes[2] ax.set_title('DFT angle') angles = np.angle(Xk) if unwrap: angles = np.unwrap(angles) ax.stem(angles) N = 9 # number of samples nd = 4 # time-delay in samples # Original and time-shifted signals xn = signal_gen(N, 0) xn_s = signal_gen(N, nd, aliasing=True) # Plot Xk, Xk_s = [sf.fft(signal) for signal in [xn, xn_s]] plot(xn, Xk, title='Unshifted signal') plot(xn_s, Xk_s, title='Time-shifted signal') # Phase differences between DFT of shifted and unshifted signals phase_wrapped = np.angle(Xk_s) - np.angle(Xk) phase = np.unwrap(phase_wrapped) # Print wrapped and unwrapped phase differences and increments print(np.array2string(phase_wrapped, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(phase, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(np.diff(phase), formatter={'float_kind': lambda x: "%.2f" % x})) # Compute time-delay pd = phase[1]-phase[0] nd2 = -N * pd / (2*np.pi) print(f'nd = {nd2:.2f}') 

When we know the phase increment $pd=2.79$, we can determine the time-delay as a number of samples:

(I'm using the general term DFT, the transform implemented by FFT algorithm.)

To get the DFT of a shifted signal the DFT of the unshifted signal $X[k]$ is multiplied by $e^{-j\frac{2\pi k}{N}n_{d}}$.

$$n_d = -\frac {N} {2 \pi}p_d$$

import numpy as np import scipy.fft as sf import matplotlib.pyplot as plt   # Generate a signal delayed or not def signal_gen(length, delay=0, aliasing=False): indices = np.arange(-delay, -delay+length) if aliasing: indices = indices % length values = np.linspace(1, 0, length) ** 2 + 0.2 xn = np.where((indices<0) | (indices>=length), 0, values[indices]) return xn # Plot signal def plot(xn, Xk, title='Signal', unwrap=False): # Plot signal fig, axes = plt.subplots(ncols=3, squeeze=True, figsize=(8, 2.5), layout='constrained') ax = axes[0] ax.set_title(title) ax.stem(xn) # Plot DFT magnitude ax = axes[1] ax.set_title('DFT magnitude') ax.stem(abs(Xk)) # Plot DFT angle ax = axes[2] ax.set_title('DFT angle') angles = np.angle(Xk) if unwrap: angles = np.unwrap(angles) ax.stem(angles) N = 9 # number of samples to create nd = 4 # time-delay in samples # Original and time-shifted signals xn = signal_gen(N, 0) xn_s = signal_gen(N, nd, aliasing=True) # Plot Xk, Xk_s = [sf.fft(signal) for signal in [xn, xn_s]] plot(xn, Xk, title='Unshifted signal') plot(xn_s, Xk_s, title='Time-shifted signal') # Phase differences between DFT of shifted and unshifted signals phase_wrapped = np.angle(Xk_s) - np.angle(Xk) phase = np.unwrap(phase_wrapped) # Print wrapped and unwrapped phase differences and increments print(np.array2string(phase_wrapped, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(phase, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(np.diff(phase), formatter={'float_kind': lambda x: "%.2f" % x})) # Compute time-delay pd = phase[1]-phase[0] nd2 = -N * pd / (2*np.pi) print(f'nd = {nd2:.2f}') 

The time-delay as a number of samples is determined from the phase increment $p_d=-2.79$:

added 2727 characters in body
Source Link
mins
  • 473
  • 3
  • 11

This answer is nothing more than an illustrated reformulation of what was said in other posts.

  1. When a time-shift is applied to a signal, it only changes the angles in the DFT coefficients.

  2. In turn, the time-shift used can determined by observing how the spectral line angles have been changed according to their index $k$.


If you take(I'm using the general name DFT of a signal (e.g. using, the transform implemented by FFT algorithm.)

The following plots show a signal, and theits DFT of the same signal time-shifted (left column below)magnitude and angle, you getand the same amplitudes for the spectral lines (center) but not the same phases (right):a shifted version.

Thus the quick answer toThis answers your first question is time: Time-shifting a signal results in a change of phase in the spectral lines.

For the second question, but not in their amplitudeshow to determine the time-shift from the DFT, nor their frequencieslet's look at how the time-shift changes the DFT.

AAs you mentioned, a change of phase is indicated by a multiplication by a complex exponential. This is consistent with the the relationship:

$$\cos(\omega t + \varphi) = \Re \{ e^{j \omega t + \varphi } \} = \Re \{ e^{j \omega t}e^{j\varphi} \}$$.$$\cos(\omega t + \varphi) = \Re \{ e^{j (\omega t + \varphi) } \} = \Re \{ e^{j \omega t}e^{j\varphi} \}$$

where adding $\varphi$ represents a phase-shift and multiplying by $e^{j\varphi}$ does the same. This leads to ..are equivalent.

TheThis pair of formulas relates the effect of time-shifting in the time-domain $\overset{\textrm{DFT}}{\longleftrightarrow}$and in the frequency-domain pair of formulas:

$$y[n]=x[((n-n_{d}))_{N}]\overset{\textrm{DFT}}{\longleftrightarrow}Y[k]=e^{-j\frac{2\pi k}{N}n_{d}}X[k]$$

for time-shifting a signal of length $N$ byand a shift of $n_d$ samples is:

$$y[n]=x[((n-n_{d}))_{N}]\overset{\textrm{DFT}}{\longleftrightarrow}Y[k]=e^{-j\frac{2\pi k}{N}n_{d}}X[k]$$

with $()_N$ indicating modulo-N.

Time-shift results in increasing phase-shiftAngle increase is different for each spectral linesline

InTo get the DFT formula we see we are multiplyingof a shifted signal the DFT of the unshifted signal is multiplied by $e^{-j\frac{2\pi k}{N}n_{d}}$ where.

Let's note $\frac{2\pi k}{N}n_{d}$ is a value proportional both to the ratio $n_d/N$ and the index of the spectral line $k$, but not dependent on the frequency, thus it is a phase change.:

  • The ratio $n_d/N$. This determines a constant angle value.
  • The index of the spectral line $k$. Since the phase angle corresponding to a given time is proportional to the frequency, this angle increases for each spectral line.

As all harmonics are shiftedThis multiplication by a variable factor applies the same time amount whenof time-shift to all spectral lines, and thus the whole signal is consistently time-shifted.

Now if the angles for the original signal are subtracted from the angles for the shifted signal, and since the same timeresult is represented byan arithmetical progression with a phase angle dependent on the harmonic frequency,common difference $p_d$.

Getting the plot shows phase changes increasingtime-shift $n_d$ from one harmonic to the next (you must mentally unwrapcommon difference:

$$n_d = -\frac {N p_d} {2 \pi}$$

Application

This piece of Python code plots the phase).images above and computes the time delay:

import numpy as np import scipy.fft as sf import matplotlib.pyplot as plt def signal_gen(length, delay=0, aliasing=False): indices = np.arange(-delay, -delay+length) if aliasing: indices = indices % length values = np.linspace(1, 0, length) ** 2 + 0.2 xn = np.where((indices<0) | (indices>=length), 0, values[indices]) return xn def plot(xn, Xk, title='Signal', unwrap=False): # Plot signal fig, axes = plt.subplots(ncols=3, squeeze=True, figsize=(8, 2.5), layout='constrained') ax = axes[0] ax.set_title(title) ax.stem(xn) # Plot spectrum ax = axes[1] ax.set_title('DFT magnitude') ax.stem(abs(Xk)) # Plot reconstructed spectrum ax = axes[2] ax.set_title('DFT angle') angles = np.angle(Xk) if unwrap: angles = np.unwrap(angles) ax.stem(angles) N = 9 # number of samples nd = 4 # time-delay in samples # Original and time-shifted signals xn = signal_gen(N, 0) xn_s = signal_gen(N, nd, aliasing=True) # Plot Xk, Xk_s = [sf.fft(signal) for signal in [xn, xn_s]] plot(xn, Xk, title='Unshifted signal') plot(xn_s, Xk_s, title='Time-shifted signal') # Phase differences between DFT of shifted and unshifted signals phase_wrapped = np.angle(Xk_s) - np.angle(Xk) phase = np.unwrap(phase_wrapped) # Print wrapped and unwrapped phase differences and increments print(np.array2string(phase_wrapped, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(phase, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(np.diff(phase), formatter={'float_kind': lambda x: "%.2f" % x})) # Compute time-delay pd = phase[1]-phase[0] nd2 = -N * pd / (2*np.pi) print(f'nd = {nd2:.2f}') 

It outputs

  • The change in angles between DFT

    [0.00 3.49 0.70 -2.09 1.40 -1.40 2.09 -0.70 -3.49]

  • The same angles unwrapped to show the increase

    [0.00 -2.79 -5.59 -8.38 -11.17 -13.96 -16.76 -19.55 -22.34]

  • The first differences

    [-2.79 -2.79 -2.79 -2.79 -2.79 -2.79 -2.79 -2.79]

The last formula allows to measureWhen we know the phase of the signalincrement $pd=2.79$, howeverwe can determine the classical method is to detect zero crossings.time-delay as a number of samples:

nd = 4.00

This answer is nothing more than an illustrated reformulation of what was said in other posts.

If you take the DFT of a signal (e.g. using the FFT algorithm), and the DFT of the same signal time-shifted (left column below), you get the same amplitudes for the spectral lines (center) but not the same phases (right):

Thus the quick answer to your question is time-shifting a signal results in a change of phase in the spectral lines, but not in their amplitudes, nor their frequencies.

A change of phase is indicated by a multiplication by a complex exponential. This is consistent with the the relationship:

$$\cos(\omega t + \varphi) = \Re \{ e^{j \omega t + \varphi } \} = \Re \{ e^{j \omega t}e^{j\varphi} \}$$.

where adding $\varphi$ represents a phase-shift and multiplying by $e^{j\varphi}$ does the same. This leads to ...

The time-domain $\overset{\textrm{DFT}}{\longleftrightarrow}$ frequency-domain pair of formulas for time-shifting a signal of length $N$ by $n_d$ samples is:

$$y[n]=x[((n-n_{d}))_{N}]\overset{\textrm{DFT}}{\longleftrightarrow}Y[k]=e^{-j\frac{2\pi k}{N}n_{d}}X[k]$$

with $()_N$ indicating modulo-N.

Time-shift results in increasing phase-shift for spectral lines

In the DFT formula we see we are multiplying the DFT of the unshifted signal by $e^{-j\frac{2\pi k}{N}n_{d}}$ where $\frac{2\pi k}{N}n_{d}$ is a value proportional to the ratio $n_d/N$ and the index of the spectral line $k$, but not dependent on the frequency, thus it is a phase change.

As all harmonics are shifted by the same time amount when the whole signal is time-shifted, and since the same time is represented by a phase angle dependent on the harmonic frequency, the plot shows phase changes increasing from one harmonic to the next (you must mentally unwrap the phase).

The last formula allows to measure the phase of the signal, however the classical method is to detect zero crossings.

  1. When a time-shift is applied to a signal, it only changes the angles in the DFT coefficients.

  2. In turn, the time-shift used can determined by observing how the spectral line angles have been changed according to their index $k$.


(I'm using the general name DFT, the transform implemented by FFT algorithm.)

The following plots show a signal, its DFT magnitude and angle, and the same for a shifted version.

This answers your first question: Time-shifting a signal results in a change of phase in the spectral lines.

For the second question, how to determine the time-shift from the DFT, let's look at how the time-shift changes the DFT.

As you mentioned, a change of phase is a multiplication by a complex exponential. This is consistent with the the relationship:

$$\cos(\omega t + \varphi) = \Re \{ e^{j (\omega t + \varphi) } \} = \Re \{ e^{j \omega t}e^{j\varphi} \}$$

where adding $\varphi$ and multiplying by $e^{j\varphi}$ are equivalent.

This pair of formulas relates the effect of time-shifting in the time-domain and in the frequency-domain:

$$y[n]=x[((n-n_{d}))_{N}]\overset{\textrm{DFT}}{\longleftrightarrow}Y[k]=e^{-j\frac{2\pi k}{N}n_{d}}X[k]$$

for a signal of length $N$ and a shift of $n_d$ samples.

Angle increase is different for each spectral line

To get the DFT of a shifted signal the DFT of the unshifted signal is multiplied by $e^{-j\frac{2\pi k}{N}n_{d}}$.

Let's note $\frac{2\pi k}{N}n_{d}$ is a value proportional both to:

  • The ratio $n_d/N$. This determines a constant angle value.
  • The index of the spectral line $k$. Since the phase angle corresponding to a given time is proportional to the frequency, this angle increases for each spectral line.

This multiplication by a variable factor applies the same amount of time-shift to all spectral lines, and thus the whole signal is consistently time-shifted.

Now if the angles for the original signal are subtracted from the angles for the shifted signal, the result is an arithmetical progression with a common difference $p_d$.

Getting the time-shift $n_d$ from the common difference:

$$n_d = -\frac {N p_d} {2 \pi}$$

Application

This piece of Python code plots the images above and computes the time delay:

import numpy as np import scipy.fft as sf import matplotlib.pyplot as plt def signal_gen(length, delay=0, aliasing=False): indices = np.arange(-delay, -delay+length) if aliasing: indices = indices % length values = np.linspace(1, 0, length) ** 2 + 0.2 xn = np.where((indices<0) | (indices>=length), 0, values[indices]) return xn def plot(xn, Xk, title='Signal', unwrap=False): # Plot signal fig, axes = plt.subplots(ncols=3, squeeze=True, figsize=(8, 2.5), layout='constrained') ax = axes[0] ax.set_title(title) ax.stem(xn) # Plot spectrum ax = axes[1] ax.set_title('DFT magnitude') ax.stem(abs(Xk)) # Plot reconstructed spectrum ax = axes[2] ax.set_title('DFT angle') angles = np.angle(Xk) if unwrap: angles = np.unwrap(angles) ax.stem(angles) N = 9 # number of samples nd = 4 # time-delay in samples # Original and time-shifted signals xn = signal_gen(N, 0) xn_s = signal_gen(N, nd, aliasing=True) # Plot Xk, Xk_s = [sf.fft(signal) for signal in [xn, xn_s]] plot(xn, Xk, title='Unshifted signal') plot(xn_s, Xk_s, title='Time-shifted signal') # Phase differences between DFT of shifted and unshifted signals phase_wrapped = np.angle(Xk_s) - np.angle(Xk) phase = np.unwrap(phase_wrapped) # Print wrapped and unwrapped phase differences and increments print(np.array2string(phase_wrapped, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(phase, formatter={'float_kind': lambda x: "%.2f" % x})) print(np.array2string(np.diff(phase), formatter={'float_kind': lambda x: "%.2f" % x})) # Compute time-delay pd = phase[1]-phase[0] nd2 = -N * pd / (2*np.pi) print(f'nd = {nd2:.2f}') 

It outputs

  • The change in angles between DFT

    [0.00 3.49 0.70 -2.09 1.40 -1.40 2.09 -0.70 -3.49]

  • The same angles unwrapped to show the increase

    [0.00 -2.79 -5.59 -8.38 -11.17 -13.96 -16.76 -19.55 -22.34]

  • The first differences

    [-2.79 -2.79 -2.79 -2.79 -2.79 -2.79 -2.79 -2.79]

When we know the phase increment $pd=2.79$, we can determine the time-delay as a number of samples:

nd = 4.00

added 1 character in body
Source Link
mins
  • 473
  • 3
  • 11
Loading
added 1 character in body
Source Link
mins
  • 473
  • 3
  • 11
Loading
Source Link
mins
  • 473
  • 3
  • 11
Loading