filtfilt() - Numerische Stabilität IIR Filter (Butterworth)
benwin
Forum-Anfänger
Beiträge: 11
Anmeldedatum: 28.01.13
Wohnort: ---
Version: R2011b
Verfasst am : 04.02.2013, 14:05
Titel : filtfilt() - Numerische Stabilität IIR Filter (Butterworth)
Bin gerade dabei, mich in Matlab einzufuchsen, und habe damit angefangen, die verschieden Implementationen von Butterworth-Filtern zu vergleichen. Also Transfer Function-, Z-P-G- und fdesign-Varianten.
Der Code führt zu zwei recht anschaulichen Bildern (einfach mal durchlaufen lassen):
Code:
% --- INVESTIGATE DIFFERENTS FILTER IMPLEMENTATIONS ----------------------
% --- HERE: BUTTERWORTH FILTERS ONLY -------------------------------------
% OBJECT ORIENTED (DSP System Toolbox)
% use actual frequencies
% fdesign: user specifies the desired characteristics of filter and
% saves those specifications in a Filter Specification Object
% design: user implements filter as dfilt object, then used to filter data
% NOT OBJECT ORIENTED (Signal Processing Toolbox)
% use normalized frequencies
% butter(), cheby1/2(), ellip(), equiripple() ... (all IIR filters)
% Convention: unit frequency = Nyquist frequency = sample frequency / 2
% 1 = fn = fs / 2
% Example: fs=1000Hz, fn=500Hz, fcut=29Hz, fcut_unit=29/500=0.058
% ------------------------------------------------------------------------
scrsz = get ( 0 ,'ScreenSize ') ;
fs = 1000 ; % sampling frequency
flop = 29 ; % low pass frequency
fhip = 2.5 ; % high pass frequency
fb = [ fhip flop] ; % band pass frequencies vector
fn = fs/2 ; % Nyquist frequency
flopn = flop/fn; % normalized low pass frequency
fhipn = fhip/fn; % normalized high pass frequency
fbn = fb./fn; % normalized band pass frequencies vector
% ------------------------------------------------------------------------
% FILTER DESIGN
n = 6 ; % order of Butterworth filter
% butter(): returns an order 2*n digital bandpass filter if
% fbn is a two-element vector
% fdesign(): n determines both the numerator and denominator orders
% for IIR filters
% Bandpass Filter -------------------------------
fiType = 'bandpass ';
% butter () - Transfer Function design - numerically unstable
[ bandB,bandA] = butter ( n,fbn,fiType) ;
fiBandTF = dfilt.df2 ( bandB,bandA) ;
% butter () - Zero-Pole-Gain design - numerically stable
[ z,p,k] = butter ( n,fbn,fiType) ;
[ sos,g] = zp2sos( z,p,k) ;
fiBandZPG = dfilt.df2sos ( sos,g) ;
% fdesign(), design() - normalized frequencies
fiSpec = fdesign.bandpass ( 'N,F3dB1,F3dB2 ',2 *n,fhipn,flopn) ;
fiBandDn = design( fiSpec,'butter ') ;
% Lowpass Filter --------------------------------
fiType = 'low ';
% butter () - Transfer Function design - numerically unstable
[ lowB,lowA] = butter ( n,flopn,fiType) ;
fiLowTF = dfilt.df2 ( lowB,lowA) ;
% butter () - Zero-Pole-Gain design - numerically stable
[ z,p,k] = butter ( n,flopn,fiType) ;
[ sos,g] = zp2sos( z,p,k) ;
fiLowZPG = dfilt.df2sos ( sos,g) ;
% fdesign(), design() - normalized frequencies
fiSpec = fdesign.lowpass ( 'N,F3dB ',n,flopn) ;
fiLowDn = design( fiSpec,'butter ') ;
% Highpass Filter --------------------------------
fiType = 'high ';
% butter () - Transfer Function design - numerically unstable
[ highB,highA] = butter ( n,fhipn,fiType) ;
fiHighTF = dfilt.df2 ( highB,highA) ;
% butter () - Zero-Pole-Gain design - numerically stable
[ z,p,k] = butter ( n,fhipn,fiType) ;
[ sos,g] = zp2sos( z,p,k) ;
fiHighZPG = dfilt.df2sos ( sos,g) ;
% fdesign(), design() - normalized frequencies
fiSpec = fdesign.highpass ( 'N,F3dB ',n,fhipn) ;
fiHighDn = design( fiSpec,'butter ') ;
% ------------------------------------------------------------------------
% TIME SIGNAL FILTERING
rng default;
duration = 0.3 ;
ns = duration*fs; % number of samples
t = linspace ( 0 ,duration,ns) ; % time vector
y = ecg( ns) '+0.25 *randn ( ns,1 ) ; % electro-cardiogram + noise
% Bandpass Filter -------------------------------
% phase distorted
yBandTF = filter ( fiBandTF,y) ;
yBandTF1D = filter ( bandB,bandA,y) ;
yBandZPG = filter ( fiBandZPG,y) ;
yBandDn = filter ( fiBandDn,y) ;
% zero-phase
yBandTF0p = filtfilt ( fiBandTF.Numerator ,1 ,y) ;
yBandTF1D0p = filtfilt ( bandB,bandA,y) ;
yBandZPG0p = filtfilt ( fiBandZPG.sosMatrix ,fiBandZPG.ScaleValues ,y) ;
yBandDn0p = filtfilt ( fiBandDn.sosMatrix ,fiBandDn.ScaleValues ,y) ;
% Lowpass Filter --------------------------------
% phase distorted
yLowTF = filter ( fiLowTF,y) ;
yLowTF1D = filter ( lowB,lowA,y) ;
yLowZPG = filter ( fiLowZPG,y) ;
yLowDn = filter ( fiLowDn,y) ;
% zero-phase
yLowTF0p = filtfilt ( fiLowTF.Numerator ,1 ,y) ;
yLowTF1D0p = filtfilt ( lowB,lowA,y) ;
yLowZPG0p = filtfilt ( fiLowZPG.sosMatrix ,fiLowZPG.ScaleValues ,y) ;
yLowDn0p = filtfilt ( fiLowDn.sosMatrix ,fiLowDn.ScaleValues ,y) ;
% Highpass Filter -------------------------------
% phase distorted
yHighTF = filter ( fiHighTF,y) ;
yHighTF1D = filter ( highB,highA,y) ;
yHighZPG = filter ( fiHighZPG,y) ;
yHighDn = filter ( fiHighDn,y) ;
% zero-phase
yHighTF0p = filtfilt ( fiHighTF.Numerator ,1 ,y) ;
yHighTF1D0p = filtfilt ( highB,highA,y) ;
yHighZPG0p = filtfilt ( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ,y) ;
yHighDn0p = filtfilt ( fiHighDn.sosMatrix ,fiHighDn.ScaleValues ,y) ;
% ------------------------------------------------------------------------
% TIME SIGNAL PLOTS
minT = 0 ; maxT = 0.3 ; % time
minY = -4 ; maxY = 4 ; % values
titPX = minT; titPY = 4.02 ; % title plot
titRX = -0.05 ; titRY = 0 ; % title row
setBorderX = @( ) xlim ( [ minT,maxT] ) ;
setBorderY = @( ) ylim ( [ minY,maxY] ) ;
titProps = { 'HorizontalAlignment ','left ','VerticalAlignment ','bottom ','Fontsize ',8 ,'Position ',[ titPX titPY] } ;
rowTxt = @( s) text ( titRX,titRY,s,'Rotation ',90 ,'HorizontalAlignment ','center ') ;
figSig = figure ( 'Name ','Filtered Time Signals ', ...
'Position ',[ scrsz( 3 ) *0.05 scrsz( 4 ) *0.1 scrsz( 3 ) *0.8 scrsz( 4 ) *0.8 ] ) ;
% Band-Passed Signals ---------------------------
subplot ( 4 ,3 ,1 ) ; plot ( t,y,'k ') ; hold on;
plot ( t,yBandTF,t,yBandTF0p,'linewidth ',1.5 ) ;
setBorderX( ) ; setBorderY( ) ;
title ( { 'filter( fiBandTF,x) ','filtfilt( fiBandTF.Numerator ,1 ,x) '} ,titProps{ :} ) ;
rowTxt( 'TF butter ( ) ') ;
subplot ( 4 ,3 ,4 ) ; plot ( t,y,'k ') ; hold on;
plot ( t,yBandTF1D,t,yBandTF1D0p,'linewidth ',1.5 ) ;
setBorderX( ) ; setBorderY( ) ;
title ( { 'filter( lowB,lowA,x) ','filtfilt( bandB,bandA,x) '} ,titProps{ :} ) ;
rowTxt( 'TF butter ( ) ') ;
subplot ( 4 ,3 ,7 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yBandZPG,t,yBandZPG0p,'linewidth ',1.5 ) ;
setBorderX( ) ; setBorderY( ) ;
title ( { 'filter( fiBandZPG,x) ','filtfilt( fiBandZPG.sosMatrix ,fiBandZPG.ScaleValues ,x) '} ,titProps{ :} ) ;
rowTxt( 'ZPG butter ( ) ') ;
subplot ( 4 ,3 ,10 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yBandDn,t,yBandDn0p,'linewidth ',1.5 ) ;
setBorderX( ) ; setBorderY( ) ;
title ( { 'filter( fiBandDn,x) ','filtfilt( fiBandDn.sosMatrix ,fiBandDn.ScaleValues ,x) '} ,titProps{ :} ) ;
rowTxt( 'fdesign( ) ') ;
% Low-Passed Signals ----------------------------
subplot ( 4 ,3 ,2 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yLowTF,t,yLowTF0p,'linewidth ',1.5 ) ;
title ( { 'filter( fiLowTF,x) ','filtfilt( fiLowTF.Numerator ,1 ,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
subplot ( 4 ,3 ,5 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yLowTF1D,t,yLowTF1D0p,'linewidth ',1.5 ) ;
title ( { 'filter( lowB,lowA,x) ','filtfilt( lowB,lowA,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
subplot ( 4 ,3 ,8 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yLowZPG,t,yLowZPG0p,'linewidth ',1.5 ) ;
title ( { 'filter( fiLowZPG,x) ','filtfilt( fiLowZPG.sosMatrix ,fiLowZPG.ScaleValues ,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
subplot ( 4 ,3 ,11 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yLowDn,t,yLowDn0p,'linewidth ',1.5 ) ;
title ( { 'filter( fiLowDn,x) ','filtfilt( fiLowDn.sosMatrix ,fiLowDn.ScaleValues ,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
% High-Passed Signals ----------------------------
subplot ( 4 ,3 ,3 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yHighTF,t,yHighTF0p,'linewidth ',1.5 ) ;
title ( { 'filter( fiHighTF,x) ','filtfilt( fiHighTF.Numerator ,1 ,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
subplot ( 4 ,3 ,6 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yHighTF1D,t,yHighTF1D0p,'linewidth ',1.5 ) ;
title ( { 'filter( highB,highA,x) ','filtfilt( highB,highA,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
subplot ( 4 ,3 ,9 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yHighZPG,t,yHighZPG0p,'linewidth ',1.5 ) ;
title ( { 'filter( fiHighZPG,x) ','filtfilt( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
subplot ( 4 ,3 ,12 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yHighDn,t,yHighDn0p,'linewidth ',1.5 ) ;
title ( { 'filter( fiHighDn,x) ','filtfilt( fiHighDn.sosMatrix ,fiHighDn.ScaleValues ,x) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
% ------------------------------------------------------------------------
% FILTER PLOTS
minR = 0 ; maxR = 2 ; % response
minF = 1e-3 ; maxF = 1 ; % frequency
titPX = minF; titPY = 2.01 ; % title plot
titRX = 2e-4 ; titRY = 1 ; % title row
stabX = 1.5 *minF; stabYr1 = 0.9 *maxR; stabYr2 = 0.78 *maxR;
setBorderX = @( ) xlim ( [ minF,maxF] ) ;
setBorderY = @( ) ylim ( [ minR,maxR] ) ;
titProps = { 'HorizontalAlignment ','left ','VerticalAlignment ','bottom ','Fontsize ',8 ,'Position ',[ titPX titPY] } ;
rowTxt = @( s) text ( titRX,titRY,s,'Rotation ',90 ,'HorizontalAlignment ','center ') ;
stabTxt = @( f,posY) text ( stabX,posY,[ 'isstable( ' inputname ( 1 ) ') : ' int2str ( isstable( f) ) ] ,'HorizontalAlignment ','left ','Fontsize ',8 ) ;
stabTxt2 = @( fB,fA,posY) text ( stabX,posY,[ 'isstable( ' inputname ( 1 ) ', ' inputname ( 2 ) ') : ' ...
int2str ( isstable( dfilt.df2 ( fB,fA) ) ) ] ,'HorizontalAlignment ','left ','Fontsize ',8 ) ;
figFil = figure ( 'Name ','Filters ', ...
'Position ',[ scrsz( 3 ) *0.05 scrsz( 4 ) *0.1 scrsz( 3 ) *0.8 scrsz( 4 ) *0.8 ] ) ;
% Bandpass Filter -------------------------------
[ magBandTF,fBandTF] =freqz ( fiBandTF,5000 ) ;
subplot ( 4 ,3 ,1 ) ;semilogx( fBandTF,abs ( magBandTF) ,'b ') ;hold on;
title ( { 'freqz( fiBandTF) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiBandTF,stabYr1) ;
rowTxt( 'TF butter ( ) ') ;
[ magBandTF1D,fBandTF1D] =freqz ( bandB,bandA,5000 ) ;
subplot ( 4 ,3 ,4 ) ;semilogx( fBandTF1D,abs ( magBandTF1D) ,'b ') ;hold on;
title ( { 'freqz( bandB,bandA) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt2( bandB,bandA,stabYr1) ;
rowTxt( 'TF butter ( ) ') ;
[ magBandZPG,fBandZPG] =freqz ( fiBandZPG,5000 ) ; % regular design
[ bandZPG_B,bandZPG_A] = sos2tf( fiBandZPG.sosMatrix ,fiBandZPG.ScaleValues ) ;
[ magBandZPG_TF,fBandZPG_TF] = freqz ( bandZPG_B,bandZPG_A,5000 ) ; % transformed desing for filtfilt()
subplot ( 4 ,3 ,7 ) ;semilogx( fBandZPG,abs ( magBandZPG) ,fBandZPG_TF,abs ( magBandZPG_TF) ) ;hold on;
title ( { 'freqz( fiBandZPG) ','freqz( bandZPG\_B,bandZPG\_A) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiBandZPG,stabYr1) ;
stabTxt2( bandZPG_B,bandZPG_A,stabYr2) ;
rowTxt( 'ZPG butter ( ) ') ;
[ magBandDn,fBandDn] =freqz ( fiBandDn,5000 ) ; % regular design
[ bandDn_B,bandDn_A] = sos2tf( fiBandDn.sosMatrix ,fiBandDn.ScaleValues ) ;
[ magBandDn_TF,fBandDn_TF] = freqz ( bandDn_B,bandDn_A,5000 ) ; % transformed desing for filtfilt()
subplot ( 4 ,3 ,10 ) ;semilogx( fBandDn,abs ( magBandDn) ,fBandDn_TF,abs ( magBandDn_TF) ) ;hold on;
title ( { 'freqz( fiBandDn) ','freqz( bandDn\_B,bandDn\_A) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiBandDn,stabYr1) ;
stabTxt2( bandDn_B,bandDn_A,stabYr2) ;
rowTxt( 'fdesign( ) ') ;
% Lowpass Filter --------------------------------
[ magLowTF,fLowTF] =freqz ( fiLowTF,5000 ) ;
subplot ( 4 ,3 ,2 ) ;semilogx( fLowTF,abs ( magLowTF) ,'b ') ;hold on;
title ( { 'freqz( fiLowTF) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiLowTF,stabYr1) ;
[ magLowTF1D,fLowTF1D] =freqz ( lowB,lowA,5000 ) ;
subplot ( 4 ,3 ,5 ) ;semilogx( fLowTF1D,abs ( magLowTF1D) ,'b ') ;hold on;
title ( { 'freqz( lowB,lowA) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt2( lowB,lowA,stabYr1) ;
[ magLowZPG,fLowZPG] =freqz ( fiLowZPG,5000 ) ; % regular design
[ lowZPG_B,lowZPG_A] = sos2tf( fiLowZPG.sosMatrix ,fiLowZPG.ScaleValues ) ;
[ magLowZPG_TF,fLowZPG_TF] = freqz ( lowZPG_B,lowZPG_A,5000 ) ; % transformed desing for filtfilt()
subplot ( 4 ,3 ,8 ) ;semilogx( fLowZPG,abs ( magLowZPG) ,fLowZPG_TF,abs ( magLowZPG_TF) ) ;hold on;
title ( { 'freqz( fiLowZPG) ','freqz( lowZPG\_B,lowZPG\_A) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiLowZPG,stabYr1) ;
stabTxt2( lowZPG_B,lowZPG_A,stabYr2) ;
[ magLowDn,fLowDn] =freqz ( fiLowDn,5000 ) ; % regular design
[ lowDn_B,lowDn_A] = sos2tf( fiLowDn.sosMatrix ,fiLowDn.ScaleValues ) ;
[ magLowDn_TF,fLowDn_TF] = freqz ( lowDn_B,lowDn_A,5000 ) ; % transformed desing for filtfilt()
subplot ( 4 ,3 ,11 ) ;semilogx( fLowDn,abs ( magLowDn) ,fLowDn_TF,abs ( magLowDn_TF) ) ;hold on;
title ( { 'freqz( fiLowDn) ','freqz( lowDn\_B,lowDn\_A) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiLowDn,stabYr1) ;
stabTxt2( lowDn_B,lowDn_A,stabYr2) ;
% Highpass Filter -------------------------------
[ magHighTF,fHighTF] =freqz ( fiHighTF,5000 ) ;
subplot ( 4 ,3 ,3 ) ;semilogx( fHighTF,abs ( magHighTF) ,'b ') ;hold on;
title ( { 'freqz( fiHighTF) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiHighTF,stabYr1) ;
[ magHighTF1D,fHighTF1D] =freqz ( highB,highA,5000 ) ;
subplot ( 4 ,3 ,6 ) ;semilogx( fHighTF1D,abs ( magHighTF1D) ,'b ') ;hold on;
title ( { 'freqz( highB,highA) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt2( highB,highA,stabYr1) ;
[ magHighZPG,fHighZPG] =freqz ( fiHighZPG,5000 ) ; % regular design
[ highZPG_B,highZPG_A] = sos2tf( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ) ;
[ magHighZPG_TF,fHighZPG_TF] = freqz ( highZPG_B,highZPG_A,5000 ) ; % transformed desing for filtfilt()
subplot ( 4 ,3 ,9 ) ;semilogx( fHighZPG,abs ( magHighZPG) ,fHighZPG_TF,abs ( magHighZPG_TF) ) ;hold on;
title ( { 'freqz( fiHighZPG) ','freqz( highZPG\_B,highZPG\_A) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiHighZPG,stabYr1) ;
stabTxt2( highZPG_B,highZPG_A,stabYr2) ;
[ magHighDn,fHighDn] =freqz ( fiHighDn,5000 ) ; % regular design
[ highDn_B,highDn_A] = sos2tf( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ) ;
[ magHighDn_TF,fHighDn_TF] = freqz ( highDn_B,highDn_A,5000 ) ; % transformed desing for filtfilt()
subplot ( 4 ,3 ,12 ) ;semilogx( fHighDn,abs ( magHighDn) ,fHighDn_TF,abs ( magHighDn_TF) ) ;hold on;
title ( { 'freqz( fiHighDn) ','freqz( highZPG\_B,highZPG\_A) '} ,titProps{ :} ) ;
setBorderX( ) ; setBorderY( ) ;
stabTxt( fiHighDn,stabYr1) ;
stabTxt2( highDn_B,highDn_A,stabYr2) ;
Jetzt zur Frage:
Dass Highpass-Filter mit niedriger Cutoff-Frequenz numerisch instabil sein können ist klar. Bandpass-Filter entsprechend. Die Transfer-Function-Form ist dabei natürlich noch instabiler als die Alternativen - was blöd ist, wenn man das Signal ohne Phasenversatz filtern möchte und auf filtfilt() angewiesen ist. filtfilt() akzeptiert ja leider keine andere Form.
Wie kann man erfahren, ob ein Filter stabil unter filtfilt() ist?
Wenn ich beispielsweise umwandle:
ergeben
beide 1, obwohl
klar instabil ist (siehe rechte Spalte im Zeitsignalplot).
Woher kommt diese Instabilität wenn nicht aus den Polen?
Grüße,
Benjamin
Jan S
Moderator
Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
Verfasst am : 04.02.2013, 20:44
Titel : Re: filtfilt() - Numerische Stabilität IIR Filter (Butterwo
Hallo Bejamin,
Beim Versuch Deinen Code laufen zu lassen, scheitert mein Matlab am Fehlern der Funktion RNG. Zur eigentlichen Frage fehlt mir also leider das Anschauungsmaterial.
Der Unterschied von FILTFILT zum doppelt angewendeten FILTER ist lediglich die besondere Methode, die versucht an den Rändern das Einschwingverhalten zu reduzieren. Es bleibt aber natürlich sowieso fraglich, ob automatisch erzeugte zusätzliche Signal-Stücke eine realistische Verlängerung des echten Signals darstellen, oder ob dies Artefakte sind. Es gibt also durchaus auch Fälle, in denen FILTFILT wissenschaftlich sinnvoll hierdurch ersetzt werden kann:
Gruß, Jan
Harald
Forum-Meister
Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
Verfasst am : 04.02.2013, 20:55
Titel :
benwin
Themenstarter
Forum-Anfänger
Beiträge: 11
Anmeldedatum: 28.01.13
Wohnort: ---
Version: R2011b
Verfasst am : 06.02.2013, 09:19
Titel :
Der Hinweis auf die Besonderheit von filtfilt() war sehr hilfreich. Ich hab jetzt zusätzlich noch die flipud()-Variante mit in mein Beispiel aufgenommen (falls es jemanden interessiert ... und ja, die rng-Zeile kann auskommentiert werden.)
Anscheinend ist es wirklich so, dass das Verhalten, dass ich als numerische Instabiliät im Ergebnis von filtfilt() interpretiert habe, tatsächlich nur ein Artefakt und mit den Ergebnisse von isstable() konsistent ist.
Danke nochmal!
Code:
% --- INVESTIGATE DIFFERENTS FILTER IMPLEMENTATIONS ----------------------
% --- HERE: BUTTERWORTH FILTERS ONLY -------------------------------------
% OBJECT ORIENTED (DSP System Toolbox)
% use actual frequencies
% fdesign: user specifies the desired characteristics of filter and
% saves those specifications in a Filter Specification Object
% design: user implements filter as dfilt object, then used to filter data
% NOT OBJECT ORIENTED (Signal Processing Toolbox)
% use normalized frequencies
% butter(), cheby1/2(), ellip(), equiripple() ... (all IIR filters)
% Convention: unit frequency = Nyquist frequency = sample frequency / 2
% 1 = fn = fs / 2
% Example: fs=1000Hz, fn=500Hz, fcut=29Hz, fcut_unit=29/500=0.058
% ------------------------------------------------------------------------
scrsz = get ( 0 ,'ScreenSize ') ;
fs = 1000 ; % sampling frequency
flop = 29 ; % low pass frequency
fhip = 2.5 ; % high pass frequency
fb = [ fhip flop] ; % band pass frequencies vector
fn = fs/2 ; % Nyquist frequency
flopn = flop/fn; % normalized low pass frequency
fhipn = fhip/fn; % normalized high pass frequency
fbn = fb./fn; % normalized band pass frequencies vector
% ------------------------------------------------------------------------
% FILTER DESIGN
n = 6 ; % order of Butterworth filter
% butter(): returns an order 2*n digital bandpass filter if
% fbn is a two-element vector
% fdesign(): n determines both the numerator and denominator orders
% for IIR filters
% Bandpass Filter -------------------------------
fiType = 'bandpass ';
% butter () - Transfer Function design
[ bandB,bandA] = butter ( n,fbn,fiType) ;
fiBandTF = dfilt.df2 ( bandB,bandA) ;
% butter () - Zero-Pole-Gain design
[ z,p,k] = butter ( n,fbn,fiType) ;
[ sos,g] = zp2sos( z,p,k) ;
fiBandZPG = dfilt.df2sos ( sos,g) ;
% fdesign(), design() - here: normalized frequencies
fiSpec = fdesign.bandpass ( 'N,F3dB1,F3dB2 ',2 *n,fhipn,flopn) ;
fiBandDn = design( fiSpec,'butter ') ;
% Lowpass Filter --------------------------------
fiType = 'low ';
% butter () - Transfer Function design
[ lowB,lowA] = butter ( n,flopn,fiType) ;
fiLowTF = dfilt.df2 ( lowB,lowA) ;
% butter () - Zero-Pole-Gain design
[ z,p,k] = butter ( n,flopn,fiType) ;
[ sos,g] = zp2sos( z,p,k) ;
fiLowZPG = dfilt.df2sos ( sos,g) ;
% fdesign(), design() - here: normalized frequencies
fiSpec = fdesign.lowpass ( 'N,F3dB ',n,flopn) ;
fiLowDn = design( fiSpec,'butter ') ;
% Highpass Filter --------------------------------
fiType = 'high ';
% butter () - Transfer Function design
[ highB,highA] = butter ( n,fhipn,fiType) ;
fiHighTF = dfilt.df2 ( highB,highA) ;
% butter () - Zero-Pole-Gain design
[ z,p,k] = butter ( n,fhipn,fiType) ;
[ sos,g] = zp2sos( z,p,k) ;
fiHighZPG = dfilt.df2sos ( sos,g) ;
% fdesign(), design() - here: normalized frequencies
fiSpec = fdesign.highpass ( 'N,F3dB ',n,fhipn) ;
fiHighDn = design( fiSpec,'butter ') ;
% ------------------------------------------------------------------------
% TIME SIGNAL FILTERING
rng default;
duration = 0.3 ;
ns = duration*fs; % number of samples
t = linspace ( 0 ,duration,ns) ; % time vector
y = ecg( ns) '+0.25 *randn ( ns,1 ) ; % electro-cardiogram + noise
% Bandpass Filter -------------------------------
% phase distorted
yBandTF = filter ( fiBandTF,y) ;
yBandTF1D = filter ( bandB,bandA,y) ;
yBandZPG = filter ( fiBandZPG,y) ;
yBandDn = filter ( fiBandDn,y) ;
% zero-phase, filtfilt()
yBandTF0p = filtfilt ( fiBandTF.Numerator ,1 ,y) ;
yBandTF1D0p = filtfilt ( bandB,bandA,y) ;
yBandZPG0p = filtfilt ( fiBandZPG.sosMatrix ,fiBandZPG.ScaleValues ,y) ;
yBandDn0p = filtfilt ( fiBandDn.sosMatrix ,fiBandDn.ScaleValues ,y) ;
% zero-phase, flipud(filter(flipud(filter())))
yBandTF0p2 = flipud ( filter ( fiBandTF,flipud ( yBandTF) ) ) ;
yBandTF1D0p2 = flipud ( filter ( bandB,bandA,flipud ( yBandTF1D) ) ) ;
yBandZPG0p2 = flipud ( filter ( fiBandZPG,flipud ( yBandZPG) ) ) ;
yBandDn0p2 = flipud ( filter ( fiBandDn,flipud ( yBandDn) ) ) ;
% Lowpass Filter --------------------------------
% phase distorted
yLowTF = filter ( fiLowTF,y) ;
yLowTF1D = filter ( lowB,lowA,y) ;
yLowZPG = filter ( fiLowZPG,y) ;
yLowDn = filter ( fiLowDn,y) ;
% zero-phase, filtfilt()
yLowTF0p = filtfilt ( fiLowTF.Numerator ,1 ,y) ;
yLowTF1D0p = filtfilt ( lowB,lowA,y) ;
yLowZPG0p = filtfilt ( fiLowZPG.sosMatrix ,fiLowZPG.ScaleValues ,y) ;
yLowDn0p = filtfilt ( fiLowDn.sosMatrix ,fiLowDn.ScaleValues ,y) ;
% zero-phase, flipud(filter(flipud(filter())))
yLowTF0p2 = flipud ( filter ( fiLowTF,flipud ( yLowTF) ) ) ;
yLowTF1D0p2 = flipud ( filter ( lowB,lowA,flipud ( yLowTF1D) ) ) ;
yLowZPG0p2 = flipud ( filter ( fiLowZPG,flipud ( yLowZPG) ) ) ;
yLowDn0p2 = flipud ( filter ( fiLowDn,flipud ( yLowDn) ) ) ;
% Highpass Filter -------------------------------
% phase distorted
yHighTF = filter ( fiHighTF,y) ;
yHighTF1D = filter ( highB,highA,y) ;
yHighZPG = filter ( fiHighZPG,y) ;
yHighDn = filter ( fiHighDn,y) ;
% zero-phase, filtfilt()
yHighTF0p = filtfilt ( fiHighTF.Numerator ,1 ,y) ;
yHighTF1D0p = filtfilt ( highB,highA,y) ;
yHighZPG0p = filtfilt ( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ,y) ;
yHighDn0p = filtfilt ( fiHighDn.sosMatrix ,fiHighDn.ScaleValues ,y) ;
% zero-phase, flipud(filter(flipud(filter())))
yHighTF0p2 = flipud ( filter ( fiHighTF,flipud ( yHighTF) ) ) ;
yHighTF1D0p2 = flipud ( filter ( highB,highA,flipud ( yHighTF1D) ) ) ;
yHighZPG0p2 = flipud ( filter ( fiHighZPG,flipud ( yHighZPG) ) ) ;
yHighDn0p2 = flipud ( filter ( fiHighDn,flipud ( yHighDn) ) ) ;
% ------------------------------------------------------------------------
% TIME SIGNAL PLOTS
minT = 0 ; maxT = 0.3 ; % time
minY = -4 ; maxY = 5 ; % values
titPX = 0.005 ; titPY = maxY-0.01 *( maxY-minY) ; % title plot
titRX = -0.05 ; titRY = 0 ; % title row
ploBorderX = @( ) xlim ( [ minT,maxT] ) ;
ploBorderY = @( ) ylim ( [ minY,maxY] ) ;
ploFontSize = @( ) set ( gca ,'FontSize ',8 ) ;
ploSize = @( ) set ( gca ,'Position ',[ 1 1 1.1 1.1 ] .* get ( gca ,'Position ') ) ;
ploFormat = @( ) cellfun ( @feval ,{ ploBorderX ploBorderY ploFontSize ploSize} ) ;
titProps = { 'HorizontalAlignment ','left ','VerticalAlignment ','top ','Position ',[ titPX titPY] } ;
rowTxt = @( s) text ( titRX,titRY,s,'Rotation ',90 ,'HorizontalAlignment ','center ') ;
legDefault = @( ) legend ( '#1 ','#2 ','#3 ') ;
legFormat = @( ) set ( legend ( gca ) ,'Position ',[ 0 0.93 0.1 0.07 ] ,'Box ','off ','Color ','none ') ;
legPlot = @( ) cellfun ( @feval ,{ legDefault legFormat} ) ;
figSig = figure ( 'Name ','Filtered Time Signals ', ...
'Position ',[ scrsz( 3 ) *0.05 scrsz( 4 ) *0.1 scrsz( 3 ) *0.8 scrsz( 4 ) *0.8 ] ) ;
% Band-Passed Signals ---------------------------
subplot ( 4 ,3 ,1 ) ;
plot ( t,yBandTF,t,yBandTF0p,t,yBandTF0p2,'linewidth ',1.5 ) ; hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiBandTF,x) ','#2 : filtfilt ( fiBandTF.Numerator ,1 ,x) ','#3 : flipud ( filter ( fiBandTF,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
rowTxt( 'TF butter ( ) ') ;
legPlot( ) ;
subplot ( 4 ,3 ,4 ) ;
plot ( t,yBandTF1D,t,yBandTF1D0p,t,yBandTF1D0p2,'linewidth ',1.5 ) ; hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( lowB,lowA,x) ','#2 : filtfilt ( bandB,bandA,x) ','#3 : flipud ( filter ( lowB,lowA,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
rowTxt( 'TF butter ( ) ') ;
subplot ( 4 ,3 ,7 ) ;
plot ( t,yBandZPG,t,yBandZPG0p,t,yBandZPG0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiBandZPG,x) ','#2 : filtfilt ( fiBandZPG.sosMatrix ,fiBandZPG.ScaleValues ,x) ','#3 : flipud ( filter ( fiBandZPG,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
rowTxt( 'ZPG butter ( ) ') ;
subplot ( 4 ,3 ,10 ) ;
plot ( t,yBandDn,t,yBandDn0p,t,yBandDn0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiBandDn,x) ','#2 : filtfilt ( fiBandDn.sosMatrix ,fiBandDn.ScaleValues ,x) ','#3 : flipud ( filter ( fiBandDn,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
rowTxt( 'fdesign( ) ') ;
% Low-Passed Signals ----------------------------
subplot ( 4 ,3 ,2 ) ;
plot ( t,yLowTF,t,yLowTF0p,t,yLowTF0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiLowTF,x) ','#2 : filtfilt ( fiLowTF.Numerator ,1 ,x) ','#3 : flipud ( filter ( fiLowTF,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
subplot ( 4 ,3 ,5 ) ;
plot ( t,yLowTF1D,t,yLowTF1D0p,t,yLowTF1D0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( lowB,lowA,x) ','#2 : filtfilt ( lowB,lowA,x) ','#3 : flipud ( filter ( lowB,lowA,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
subplot ( 4 ,3 ,8 ) ;
plot ( t,yLowZPG,t,yLowZPG0p,t,yLowZPG0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiLowZPG,x) ','#2 : filtfilt ( fiLowZPG.sosMatrix ,fiLowZPG.ScaleValues ,x) ','#3 : flipud ( filter ( fiLowZPG,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
subplot ( 4 ,3 ,11 ) ;
plot ( t,yLowDn,t,yLowDn0p,t,yLowDn0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiLowDn,x) ','#2 : filtfilt ( fiLowDn.sosMatrix ,fiLowDn.ScaleValues ,x) ','#3 : flipud ( filter ( fiLowDn,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
% High-Passed Signals ----------------------------
subplot ( 4 ,3 ,3 ) ;
plot ( t,yHighTF,t,yHighTF0p,t,yHighTF0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiHighTF,x) ','#2 : filtfilt ( fiHighTF.Numerator ,1 ,x) ','#3 : flipud ( filter ( fiHighTF,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
subplot ( 4 ,3 ,6 ) ;
plot ( t,yHighTF1D,t,yHighTF1D0p,t,yHighTF1D0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( highB,highA,x) ','#2 : filtfilt ( highB,highA,x) ','#3 : flipud ( filter ( highB,highA,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
subplot ( 4 ,3 ,9 ) ;
plot ( t,yHighZPG,t,yHighZPG0p,t,yHighZPG0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiHighZPG,x) ','#2 : filtfilt ( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ,x) ','#3 : flipud ( filter ( fiHighZPG,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
subplot ( 4 ,3 ,12 ) ;plot( t,y,'k ') ;hold on;
plot ( t,yHighDn,t,yHighDn0p,t,yHighDn0p2,'linewidth ',1.5 ) ;hold on;
plot ( t,y,'k ') ;
ploFormat( ) ;
title ( { '#1 : filter ( fiHighDn,x) ','#2 : filtfilt ( fiHighDn.sosMatrix ,fiHighDn.ScaleValues ,x) ','#3 : flipud ( filter ( fiHighDn,flipud ( #1 ) ) ) '} ,titProps{ :} ) ;
% ------------------------------------------------------------------------
% FILTER PLOTS
minR = 0 ; maxR = 2 ; % response
minF = 1e-3 ; maxF = 1 ; % frequency
titPX = 1.2 *minF; titPY = maxR-0.01 *( maxR-minR) ; % title plot
titRX = 2e-4 ; titRY = 1 ; % title row
stabX = 1.2 *minF; stabYr1 = 0.5 *maxR; stabYr2 = 0.38 *maxR; stabY = 0.01 *maxR;
ploBorderX = @( ) xlim ( [ minF,maxF] ) ;
ploBorderY = @( ) ylim ( [ minR,maxR] ) ;
ploFontSize = @( ) set ( gca ,'FontSize ',8 ) ;
ploSize = @( ) set ( gca ,'Position ',[ 1 1 1.1 1.1 ] .* get ( gca ,'Position ') ) ;
ploFormat = @( ) cellfun ( @feval ,{ ploBorderX ploBorderY ploFontSize ploSize} ) ;
titProps = { 'HorizontalAlignment ','left ','VerticalAlignment ','top ','Position ',[ titPX titPY] } ;
rowTxt = @( s) text ( titRX,titRY,s,'Rotation ',90 ,'HorizontalAlignment ','center ') ;
legDefault = @( ) legend ( '#1 ','#2 ') ;
legFormat = @( ) set ( legend ( gca ) ,'Position ',[ 0 0.95 0.1 0.05 ] ,'Box ','off ','Color ','none ') ;
legPlot = @( ) cellfun ( @feval ,{ legDefault legFormat} ) ;
stabiTxt = @( i) text ( stabX,stabY,[ 'isstable( #1 ) : ' int2str ( i) ] ,'HorizontalAlignment ','left ','VerticalAlignment ','bottom ','Fontsize ',8 ) ;
stabiTxt2 = @( i1,i2) text ( stabX,stabY,{ [ 'isstable( #1 ) : ' int2str ( i1) ] ,[ 'isstable( #2 ) : ' int2str ( i2) ] } ,'HorizontalAlignment ','left ','VerticalAlignment ','bottom ','Fontsize ',8 ) ;
figFil = figure ( 'Name ','Filters ', ...
'Position ',[ scrsz( 3 ) *0.05 scrsz( 4 ) *0.1 scrsz( 3 ) *0.8 scrsz( 4 ) *0.8 ] ) ;
% Bandpass Filter -------------------------------
[ magBandTF,fBandTF] =freqz ( fiBandTF,5000 ) ;
subplot ( 4 ,3 ,1 ) ;
semilogx ( fBandTF,abs ( magBandTF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiBandTF) '} ,titProps{ :} ) ;
stabiTxt( isstable( fiBandTF) ) ;
rowTxt( 'TF butter ( ) ') ;
[ magBandTF1D,fBandTF1D] =freqz ( bandB,bandA,5000 ) ;
subplot ( 4 ,3 ,4 ) ;
semilogx ( fBandTF1D,abs ( magBandTF1D) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( bandB,bandA) '} ,titProps{ :} ) ;
stabiTxt( isstable( dfilt.df2 ( bandB,bandA) ) ) ;
rowTxt( 'TF butter ( ) ') ;
[ magBandZPG,fBandZPG] =freqz ( fiBandZPG,5000 ) ; % regular design
[ bandZPG_B,bandZPG_A] = sos2tf( fiBandZPG.sosMatrix ,fiBandZPG.ScaleValues ) ;
[ magBandZPG_TF,fBandZPG_TF] = freqz ( bandZPG_B,bandZPG_A,5000 ) ; % transformed design for filtfilt()
subplot ( 4 ,3 ,7 ) ;
semilogx ( fBandZPG,abs ( magBandZPG) ,fBandZPG_TF,abs ( magBandZPG_TF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiBandZPG) ','#2 : freqz ( bandZPG\_B,bandZPG\_A) '} ,titProps{ :} ) ;
stabiTxt2( isstable( fiBandZPG) ,isstable( dfilt.df2 ( bandZPG_B,bandZPG_A) ) ) ;
rowTxt( 'ZPG butter ( ) ') ;
legPlot( ) ;
[ magBandDn,fBandDn] =freqz ( fiBandDn,5000 ) ; % regular design
[ bandDn_B,bandDn_A] = sos2tf( fiBandDn.sosMatrix ,fiBandDn.ScaleValues ) ;
[ magBandDn_TF,fBandDn_TF] = freqz ( bandDn_B,bandDn_A,5000 ) ; % transformed design for filtfilt()
subplot ( 4 ,3 ,10 ) ;
semilogx ( fBandDn,abs ( magBandDn) ,fBandDn_TF,abs ( magBandDn_TF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiBandDn) ','#2 : freqz ( bandDn\_B,bandDn\_A) '} ,titProps{ :} ) ;
stabiTxt2( isstable( fiBandDn) ,isstable( dfilt.df2 ( bandDn_B,bandDn_A) ) ) ;
rowTxt( 'fdesign( ) ') ;
% Lowpass Filter --------------------------------
[ magLowTF,fLowTF] =freqz ( fiLowTF,5000 ) ;
subplot ( 4 ,3 ,2 ) ;
semilogx ( fLowTF,abs ( magLowTF) ,'b ') ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiLowTF) '} ,titProps{ :} ) ;
stabiTxt( isstable( fiLowTF) ) ;
[ magLowTF1D,fLowTF1D] =freqz ( lowB,lowA,5000 ) ;
subplot ( 4 ,3 ,5 ) ;
semilogx ( fLowTF1D,abs ( magLowTF1D) ,'b ') ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( lowB,lowA) '} ,titProps{ :} ) ;
stabiTxt( isstable( dfilt.df2 ( lowB,lowA) ) ) ;
[ magLowZPG,fLowZPG] =freqz ( fiLowZPG,5000 ) ; % regular design
[ lowZPG_B,lowZPG_A] = sos2tf( fiLowZPG.sosMatrix ,fiLowZPG.ScaleValues ) ;
[ magLowZPG_TF,fLowZPG_TF] = freqz ( lowZPG_B,lowZPG_A,5000 ) ; % transformed design for filtfilt()
subplot ( 4 ,3 ,8 ) ;
semilogx ( fLowZPG,abs ( magLowZPG) ,fLowZPG_TF,abs ( magLowZPG_TF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiLowZPG) ','#2 : freqz ( lowZPG\_B,lowZPG\_A) '} ,titProps{ :} ) ;
stabiTxt2( isstable( fiLowZPG) ,isstable( dfilt.df2 ( lowZPG_B,lowZPG_A) ) ) ;
[ magLowDn,fLowDn] =freqz ( fiLowDn,5000 ) ; % regular design
[ lowDn_B,lowDn_A] = sos2tf( fiLowDn.sosMatrix ,fiLowDn.ScaleValues ) ;
[ magLowDn_TF,fLowDn_TF] = freqz ( lowDn_B,lowDn_A,5000 ) ; % transformed design for filtfilt()
subplot ( 4 ,3 ,11 ) ;
semilogx ( fLowDn,abs ( magLowDn) ,fLowDn_TF,abs ( magLowDn_TF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiLowDn) ','#2 : freqz ( lowDn\_B,lowDn\_A) '} ,titProps{ :} ) ;
stabiTxt2( isstable( fiLowDn) ,isstable( dfilt.df2 ( lowDn_B,lowDn_A) ) ) ;
% Highpass Filter -------------------------------
[ magHighTF,fHighTF] =freqz ( fiHighTF,5000 ) ;
subplot ( 4 ,3 ,3 ) ;
semilogx ( fHighTF,abs ( magHighTF) ,'b ') ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiHighTF) '} ,titProps{ :} ) ;
stabiTxt( isstable( fiHighTF) ) ;
[ magHighTF1D,fHighTF1D] =freqz ( highB,highA,5000 ) ;
subplot ( 4 ,3 ,6 ) ;
semilogx ( fHighTF1D,abs ( magHighTF1D) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( highB,highA) '} ,titProps{ :} ) ;
stabiTxt( isstable( dfilt.df2 ( highB,highA) ) ) ;
[ magHighZPG,fHighZPG] =freqz ( fiHighZPG,5000 ) ; % regular design
[ highZPG_B,highZPG_A] = sos2tf( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ) ;
[ magHighZPG_TF,fHighZPG_TF] = freqz ( highZPG_B,highZPG_A,5000 ) ; % transformed design for filtfilt()
subplot ( 4 ,3 ,9 ) ;
semilogx ( fHighZPG,abs ( magHighZPG) ,fHighZPG_TF,abs ( magHighZPG_TF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiHighZPG) ','#2 : freqz ( highZPG\_B,highZPG\_A) '} ,titProps{ :} ) ;
stabiTxt2( isstable( fiHighZPG) ,isstable( dfilt.df2 ( highZPG_B,highZPG_A) ) ) ;
[ magHighDn,fHighDn] =freqz ( fiHighDn,5000 ) ; % regular design
[ highDn_B,highDn_A] = sos2tf( fiHighZPG.sosMatrix ,fiHighZPG.ScaleValues ) ;
[ magHighDn_TF,fHighDn_TF] = freqz ( highDn_B,highDn_A,5000 ) ; % transformed design for filtfilt()
subplot ( 4 ,3 ,12 ) ;
semilogx ( fHighDn,abs ( magHighDn) ,fHighDn_TF,abs ( magHighDn_TF) ) ;hold on;
ploFormat( ) ;
title ( { '#1 : freqz ( fiHighDn) ','#2 : freqz ( highZPG\_B,highZPG\_A) '} ,titProps{ :} ) ;
stabiTxt2( isstable( fiHighDn) ,isstable( dfilt.df2 ( highDn_B,highDn_A) ) ) ;
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
Impressum
| Nutzungsbedingungen
| Datenschutz
| FAQ
| RSS
Hosted by:
Copyright © 2007 - 2024
goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.