VF_filter | VD_filter | VE_filter |
VCF_filter | VCD_filter | VCE_filter |
VFb_filter | VDb_filter | VEb_filter |
VCFb_filter | VCDb_filter | VCEb_filter |
|
Funktion | Frequenz-Filterung |
|
Syntax C/C++ | #include <VFstd.h>
void VF_filter(fVector Y, fVector X, fVector Flt, ui size );
void VFb_filter(fVector Y, fVector X, fVector Flt, ui size, fVector Buf ); |
C++ VecObj | #include <OptiVec.h>
void vector<T>::filter( const vector<T>& X, const vector<T>& Flt );
void vector<T>::b_filter( const vector<T>& X, const vector<T>& Flt, vector<T>& Buf ); |
Pascal/Delphi | uses VFstd;
procedure VF_filter( Y, X, Flt:fVector; size:UIntSize );
procedure VFb_filter( Y, X, Flt:fVector; size:UIntSize; Buf:fVector ); |
|
CUDA-Funktion C/C++ | #include <cudaVFstd.h>
int cudaVF_filter(fVector d_Y, fVector d_X, fVector d_Flt, ui size );
void VFcu_filter(fVector h_Y, fVector h_X, fVector h_Flt, ui size );
|
CUDA-Funktion Pascal/Delphi | uses VFstd;
function cudaVF_filter( d_Y, d_X, d_Flt:fVector; size:UIntSize ): IntBool;
procedure VFcu_filter( h_Y, h_X, h_Flt:fVector; size:UIntSize );
|
|
Beschreibung | Das Frequenzfilter Flt wird auf den Vektor X angewendet. Intern wird hierzu eine Fourier-Transformation durchgeführt, die Transformierte mit Flt multipliziert und das Ergebnis wieder zurücktransformiert.
Komplexe Versionen: X, Y und der Filter Flt sind komplexe Vektoren.
Reelle Versionen: X und Y sind reell. Flt muss in dem bei VF_FFT beschriebenen gepackten komplexen Format vorliegen, das man automatisch durch Erzeugung des Filters mittels
VF_FFT, VF_convolve oder VF_deconvolve erhält.
Intern benötigt VF_filter zusätzlichen Pufferspeicher, der automatisch reserviert und wieder freigegeben wird. Bei wiederholten Aufrufen wäre dies ineffizient. Es wird empfohlen, für solche Fälle stattdessen VFb_filter zu verwenden. Die Größe von Buf muss dabei ≥ size sein. Außerdem muss Buf 128-bit (P8) bzw. 256-bit( P9) ausgerichtet sein. Um dies zu garantieren, sollte man nur Vektoren als Buf verwenden, die mit der VF_vector-Familie alloziert wurden.
Für rein reelle, analytisch bekannte Filterfunktionen konstruiere man den Filter, indem man ihn zunächst für einen reellen Vektor von size/2+1 Elementen berechnet und diesen reellen Vektor anschließen in Flt kopiert, wie in dem folgenden Beispiel (fNyquist = 0.5 / Abtast-Intervall; die gewünschte Grenzwinkelfrequenz ist fGrenz): |
Beispiel C/C++: | float Coeffs[3] = {1.0, 1.4142135, 1.0};
fVector Flt = VF_vector0( size );
fVector RealFlt = VF_vector( size/2+1 );
fVector Freq = VF_vector( size/2+1 );
VF_ramp( Freq, size/2+1, 0, (fNyquist / fGrenz) / (size/2) );
/* normierte Frequenzen von 0 bis fNyquist / fGrenz */
VF_poly( RealFlt, Freq, size/2+1, Coeffs, 2 );
VF_inv( RealFlt, RealFlt, size/2+1 );
/* Übertragungsfunktion aus Koeffizienten dieses Filters 2. Ordnung berechnen */
VF_RetoC( (cfVector)Flt, RealFlt, size/2 );
/* Imaginärteile bleiben 0 */
Flt[1] = RealFlt[ size/2 ]; /* Übertragungsfunktion bei der Nyquist-Frequenz */
VF_filter( Y, X, Flt, size ); /* Anwendung des gerade konstruierten Filters auf X */ |
Dasselbe Beispiel für Pascal/Delphi: | const Coeffs: array[0..2] of Single = (1.0, 1.4142135, 1.0);
var Flt, RealFlt, Freq: fVector;
size_2: UIntSize;
begin
...
size_2 := size div 2;
Flt := VF_vector0( size );
RealFlt := VF_vector( size_2+1 );
Freq := VF_vector( size_2+1 );
VF_ramp( Freq, size_2+1, 0, (fNyquist / fGrenz) / (size_2) );
(* normierte Frequenzen von 0 bis fNyquist / fGrenz *)
VF_poly( RealFlt, Freq, size_2+1, @Coeffs, 2 );
VF_inv( RealFlt, RealFlt, size_2+1 );
(* Übertragungsfunktion aus Koeffizienten dieses Filters 2. Ordnung berechnen *)
VF_RetoC( cfVector(Flt), RealFlt, size_2 );
(* Imaginärteile bleiben 0 *)
VF_Pelement( Flt, 1 )^ := VF_element( RealFlt, size_2 );
(* Übertragungsfunktion bei der Nyquist-Frequenz *)
VF_filter( Y, X, Flt, size ); (* Anwendung des gerade konstruierten Filters auf X *)
end;
Für nicht-periodisches X besteht die Gefahr von Rand-Effekten. Man sollte X in die Mitte eines doppelt so großen Vektors kopieren, so dass an beiden Enden genügend Nullen für die erforderliche Isolation sorgen. VF_filter ist dann auf den so erhaltenen größeren Vektor anzuwenden (siehe VF_convolve).
|
|
Fehlerbehandlung | Wenn size nicht eine Potenz von 2 ist, meldet sich VF_FFT (worauf VF_filter basiert) mit der Fehlermeldung "Size must be integer power of 2." und bricht das Programm ab. |
|
|
|