VF_xspectrumVD_xspectrumVE_xspectrum
VF_xspectrumAbsVD_xspectrumAbsVE_xspectrumAbs
VFb_xspectrumVDb_xspectrumVEb_xspectrum
VFb_xspectrumAbsVDb_xspectrumAbsVEb_xspectrumAbs
FunctionCross Spectral Density (CSD) of two signals
Syntax C/C++#include <VFstd.h>
void VF_xspectrum( cfVector Spc, ui specsiz, fVector X, fVector Y, ui xsiz, fVector Win );
float VF_xspectrumAbs( fVector Spc, ui specsiz, fVector X, fVector Y, ui xsiz, fVector Win );
void VFb_xspectrum( cfVector Spc, ui specsiz, fVector X, fVector Y, ui xsiz, fVector Win, fVector Buf );
float VFb_xspectrumAbs( fVector Spc, ui specsiz, fVector X, fVector Y, ui xsiz, fVector Win, fVector Buf );
C++ VecObj#include <OptiVec.h>
void vector<complex<T>>::xspectrum( const vector<T>& X, const vector<T>& Y, const vector<T>& Win );
T vector<T>::xspectrumAbs( const vector<T>& X, const vector<T>& Y, const vector<T>& Win );
void vector<complex<T>>::b_xspectrum( const vector<T>& X, const vector<T>& Y, const vector<T>& Win, vector<T>& Buf );
T vector<T>::b_xspectrumAbs( const vector<T>& X, const vector<T>& Y, const vector<T>& Win, vector<T>& Buf );
Pascal/Delphiuses VFstd;
procedure VF_xspectrum( Spc:cfVector; specsiz:UIntSize; X,Y:fVector; xsiz:UIntSize; Win:fVector );
function VF_xspectrumAbs( Spc:fVector; specsiz:UIntSize; X,Y:fVector; xsiz:UIntSize; Win:fVector ): Single;
procedure VFb_xspectrum( Spc:cfVector; specsiz:UIntSize; X,Y:fVector; xsiz:UIntSize; Win, Buf:fVector );
function VFb_xspectrumAbs( Spc:fVector; specsiz:UIntSize; X,Y:fVector; xsiz:UIntSize; Win, Buf:fVector ): Single;
CUDA Function C/C++#include <cudaVFstd.h>
int cudaVF_xspectrum( cfVector d_Spc, ui specsiz, fVector d_X, fVector d_Y, ui xsiz, fVector d_Win );
void VFcu_xspectrum( cfVector h_Spc, ui specsiz, fVector h_X, fVector h_Y, ui xsiz, fVector h_Win );
int cudaVF_xspectrumAbs( float *h_csdfNyq, fVector d_Spc, ui specsiz, fVector d_X, fVector d_Y, ui xsiz, fVector d_Win );
int cusdVF_xspectrumAbs( float *d_csdfNyq, fVector d_Spc, ui specsiz, fVector d_X, fVector d_Y, ui xsiz, fVector d_Win );
float VFcu_xspectrumAbs( fVector h_Spc, ui specsiz, fVector h_X, fVector h_Y, ui xsiz, fVector h_Win );
CUDA Function Pascal/Delphiuses VFstd;
function cudaVF_xspectrum( d_Spc:cfVector; specsiz:UIntSize; d_X, d_Y:fVector; xsiz:UIntSize; d_Win:fVector ): IntBool;
procedure VFcu_xspectrum( h_Spc:fVector; specsiz:UIntSize; h_X, h_Y:fVector; xsiz:UIntSize; h_Win:fVector );
function cudaVF_xspectrumAbs( var h_csdfNyq:Single; d_Spc:fVector; specsiz:UIntSize; d_X, d_Y:fVector; xsiz:UIntSize; d_Win:fVector ): IntBool;
function cusdVF_xspectrumAbs( d_csdfNyq:PSingle; d_Spc:fVector; specsiz:UIntSize; d_X, d_Y:fVector; xsiz:UIntSize; d_Win:fVector ): IntBool;
function VFcu_xspectrumAbs( h_Spc:fVector; specsiz:UIntSize; h_X, h_Y:fVector; xsiz:UIntSize; h_Win:fVector ): Single;
DescriptionThe Cross Spectral Density CSD of the two data sets X and Y is calculated. It is defined as the product of the Fourier Transform of X and the complex conjugate of the Fourier Transform of Y:
SXY = F(X) * F*(Y).
As the result is identical for negative and positive frequencies, here the so-called one-sided CSD is stored:
GXY = SXY for f=0,  GXY = 2*SXY for f>0.

The result is complex (except in the case of X = Y, when the CSD is equal to the PSD, calculated by VF_spectrum). Only the values for the frequencies f=0 and f= fNyquist are real. Correspondingly, VF_xspectrum can store the result in compacted from in a complex vector of length specsiz, whereby Spc[0].Re = GXY[0] and Spc[0].Im = GXY[fNyquist].

As the CSD is often not needed in complex form, but only as its absolute value, here a second form of the function exists, VF_xspectrumAbs, which stores this absolute value as the (real) vector Spc. In order to keep specsiz an integer power of 2, there are only specsiz points stored in Spc and the last one, the CSD at the Nyquist frequency fNyquist = 0.5 / sampling_interval, is given as the return value of the function. It may either be neglected (by calling the function like a void function) or stored as the last element in Spc by calling the function as
Spc[specsiz] = VF_xspectrumAbs( Spc, specsiz, X, Y, xsiz, Win );
in this case, Spc must have a length of specsiz+1.

xsiz must be at least 2*specsiz, and specsiz has to be an integer power of 2. Internally, X is divided into (xsiz/specsiz)−1 segments and the average over the spectra of the individual segments is calculated. Each segment of length 2*specsiz yields the CSD for specsiz+1 frequencies (see VF_FFT).

Win is a window that is applied to the data segments. The size of the Win vector must be 2*specsiz. Within the VectorLib library, three functions are available that give suitable Windows: VF_Welch,   VF_Parzen, and VF_Hann. A square window (i.e. no windowing at all) is achieved by setting all elements of Win to 1.0 using VF_equ1. Use of the square window is not recommended here, though.

Internally, VF_xspectrum / VF_xspectrumAbs allocate and frees additional workspace memory. For repeated calls, this would be inefficient. In such a case, it is recommended to use VFb_xspectrum / VFb_xspectrumAbs instead. The size of Buf must be ≥ 4*xsiz + 4*specsiz. Additionally, Buf must be 128-bit (P8) or 256-bit (P9) aligned. This usually means you can only take a vector allocated by the VF_vector family as Buf.

Error handlingIf size is not a power of 2, VF_FFT (on which VF_xspectrum is based) complains "Size must be an integer power of 2" and the program is aborted.
Return valueVF_xspectrum: none.
VF_xspectrumAbs: CSD at the Nyquist frequency
See alsoVF_FFT,   VF_coherence   VF_spectrum,   VF_convolve,   VF_autocorr,   VF_xcorr,   VF_filter

VectorLib Table of Contents  OptiVec home