# Frequency shifting with complex exponential

I'm trying to frequency shift a sine wave at 50kHz by using a complex exponential at 15kHz. I should be getting an FFT with a peak at 65kHz.

Instead I'm getting a strange looking peak at 52.4kHz. Anyone know why this is?

This is probably a simple issue but I've been stuck for too long.

Here is my Matlab code:

clc,clear
close all

srate = 300e3;
npnts = srate*5;    %generate number of points for 5 seconds of sampling
time = (0:npnts-1)/srate;

% signal settings
freq1 = 50e3;
ampl = 1;
signal = ampl*sin(2*pi*freq1*time);

% amplitude spectrum via Fourier transform
signalX = fft(signal);
signalAmp = 2*abs(signalX)/npnts;   % need to multiply by 2 to recover amplitude from negative freqs
% divide by npnts to normalize fourier coefficients

% shift signal using complex exp
freq2 = 15e3;
shift = exp(1i*freq2*time).*signal;
signalshift = fft(shift);
signalAmpshift = 2*abs(signalshift)/npnts;

% vector of frequencies in kHz
hz = linspace(0,srate/2,floor(npnts/2)+1)/1e3;  %go from 0 to nyquist, frequency resolution is defined by last term

ns=1;
xlimits = [(freq1-ns*freq2)/1e3 (freq1+ns*freq2)/1e3];

figure(1);
stem(hz,signalAmp(1:length(hz)),'ks','linew',2,'markersize',10)
hold on
stem(hz,signalAmpshift(1:length(hz)),'linew',2,'markersize',10)
xlim(xlimits)
legend({'Signal';'Shifted'})


• For starters, you are missing a factor of $2\pi$ in your complex exponential. But more importantly, your input signal should be analytic before you shift it. Apr 4, 2023 at 18:05
• @Jazzmaniac what do you mean analytic? Apr 4, 2023 at 18:12
• add the $2\pi$ factor, you'll get your peak at 65Hz
– Jdip
Apr 4, 2023 at 18:31
• @PrematureCorn analytic signals have no negative frequency components. You real-valued 50 kHz sine has a frequency component at +50 kHz, and one at -50 kHz. After shifting, it would have one at -45 kHz and one at +65 kHz. That might, or might not be (and I think that's what Jazzmaniac is understandably assuming here) what you want. Apr 4, 2023 at 18:36
• Please don't abandon your questions. Jdip put effort into providing a working answer, which you have not even upvoted. I have no interest in answering such users. Apr 5, 2023 at 15:02

1. Your complex exponential is missing a factor of $$2\pi$$ hence you are not shifting by 15 kHz but by $$15/(2\pi) kHz = 2.837 kHz$$
2. The shifted frequency is not an integer multiple of the frequency resolution (sampler rate divided by FFT length) so you don't get a single line but "spectral leakage"
3. Your input signal is real, i.e. it has equal (but conjugate) amounts of positive and negative frequencies. After multiplying the signal is complex. You are shifting both frequency component of the original signal the same way. Make sure you look at the "correct" components.
• Could you please add to your answer what the "correct" components are? Also, what would be the best practice of handling a real signal multiplied by a complex exponential? Should I filter it? Apr 4, 2023 at 19:29
• @PrematureCorn: "correct" in this context depends really on what exactly you want to do and why. There are some applications where complex signals are perfectly fine and others where they really don't make sense. Apr 4, 2023 at 20:58
• @PrematureCorn this may help: $2\cos(2\pi 50e3 t) = e^{j2\pi 50e3 t}+e^{-j2\pi 50e3 t}$, which is how we see directly the positive 50KHz and negative 50KHz frequencies (which appear as two bins in the FFT). If you multiply that by $e^{j2\pi 15e3 t}$ you get $e^{j2\pi 65e3 t}+e^{-j2\pi 35e3 t}$. If you only wanted the 65KHz, you either need to high pass filter, or use the analytic signal as explained in the comments under your post. Apr 5, 2023 at 2:44
• @PrematureCorn If Hilmar answered your primary question, please select it to close this out. Review your other questions as well if still open and let the responders know what is missing still in your understanding. Thanks! Apr 5, 2023 at 21:21

signal 1

frt = 300e3;         % [Hz] sampling rate
dt=1                 % 1 second observation time
n = frt*dt           %  amount time samples
t = (0:n-1)/frt;     % [s] time reference

% signal 1
f1 = 50e3;           % [Hz]
A1 = 1;
s1 = A1*sin(2*pi*f1*t);


Put enough frequency samples in F to avoid low resolution.

When F = frt*[0:n]/n resulting FFT amplitudes show errors > 10%.

Use more frequencies than time samples to avoid FFT amplitude low resolution.

nf=4*n                    % amaount frequency samples
F = frt*[0:nf]/nf;        % [Hz] FFT frequency reference

S1 = 1/(n)*fft(s1,nf);    % not centered
S1_amp = abs(S1);

S1c_amp=abs(fftshift(S1));    % centered S1 FFT
F1c=frt*[-nf/2:nf/2]/nf;            % centered frequency reference

figure(1)
plot(F1c(1:min(numel(F1c),numel(S1c_amp))),S1c_amp(1:min(numel(F1c),numel(S1c_amp))));
grid on
xlabel('f [Hz]')
title('2-side centered FFT(s1) : s1=A*sin(2*pi*f1*t)')


S1p_amp=2*S1_amp;F1p=F;    % F1p S1p are just for 1-side |FFT| display
S1p_amp(nf/2+1:end)=[];
F1p(nf/2+1:end)=[];

figure(2)
plot(F1p,S1p_amp)
grid on
xlabel('f [Hz]')
title('1-side FFT(s1)')


signal 2

Corrected 2*pi missing in s2 exponential

f2 = 15e3;                 % [Hz]
A2=1;
s2 = A2*exp(1j*2*pi*f2*t);
S2 = 1/n*fft(s2,nf);

S2c_amp = abs(fftshift(S2));

figure(3)
plot(F1c(1:min(numel(F1c),numel(S2c_amp))),S2c_amp(1:min(numel(F1c),numel(S2c_amp))));
grid on
xlabel('f [Hz]')
title('2-side centered FFT(s2)  :  s2=A*exp(1j*2*pi*t)')


*frequency shift s3=s1.s2

s3 = s1.*s2;
S3 = 1/n*fft(s3,nf);
S3c_amp = abs(fftshift(S3));

figure(4)
plot(F1c(1:min(numel(F1c),numel(S3c_amp))),S3c_amp(1:min(numel(F1c),numel(S3c_amp))));
% plot(F1c,S3c_amp)
grid on
xlabel('f [Hz]')
title('2-side centered FFT(s2) : s3=s1*s2')


Using stem for FFT signals may clutter small peaks.