I am building a function that computes the PSD and RMS power in a time series. Idon't have a license to the DSP library.
Below my function, and a test file. When ran 'as is', it computes the RMS power based on the time series (variable: avPow) and the RMS power using the PSD (variable: r). For a simple (complete) sine wave, it return the correct value of 0.5*sqrt(2).
With the other test signal it can be shown that the amplitudes in the fft are correct.
My question: apparently, with PSD = (signalFFT(1:n) .* signalFFT(1:n)); RMS = 0.5 * sqrt(sum(PSD)/n*Fs)
variable r returns the correct result. Why is there a factor 0.5?
Any help is much appreciated.
Test file:
clear clc close format compact
Fs = 1000; % sample frequency t = 0:1/Fs:1; % time x = sin(2*pi*t); % > rms of sin(x) = 1/sqrt(2)
% x = 1 + sin(2.5*pi*t) + 2*cos(0.5*pi*t); % x = 2*cos(2*pi*t*10)+cos(2*pi*t*20); % x = 0.3*randn(size(t, 1), size(t, 2)); % plot(t, x)
n = size(t, 2); % number of data points avPow = sqrt(1 / n * sum((x - mean(x)) .* (x - mean(x)))); % average power based on time series [f, p, r] = computePSD(x, 1/Fs, false); % f: frequencies; p: power; r: rms power
disp(avPow) disp(r)
Function: function [ F, PSD, RMS ] = computePSD( signal, sampleTime, plotFigs ) [r, c] = size(signal); L = max(r, c);
if (c ~= 1 && r ~= 1)
error('encountered non-row or non-column array');
end
Fs = 1 / sampleTime;
F = Fs * (0:(L/2)) / L;
[r2, c2] = size(F);
n = max( r2, c2);
signal = signal - mean(signal);
signalFFT = 2 * abs(fft(signal)) / L;
PSD = (signalFFT(1:n) .* signalFFT(1:n));
RMS = 0.5 * sqrt(sum(PSD)/n*Fs);
if (plotFigs)
figure
loglog(F, signalFFT(1:n));
title('FFT of signal');
xlabel('Frequency (Hz)');
ylabel('|signal(f)|');
figure
loglog(F, PSD)
title('PSD of signal');
xlabel('Frequency (Hz)')
ylabel('|signal^2 / Hz|')
end
end