Forum: Digitale Signalverarbeitung / DSP / Machine Learning Subsample genaue Verschiebung von komplexen Daten, MATLAB


von T. H. (Firma: student) (cotton)


Lesenswert?

Hallo zusammen,

ich habe ein komplexes Tiefpass-Signal in matlab vorliegen(komplexe 
Daten im Zeitbereich), das ich um ein halbes Sample verschieben muss.
Fuer diese Problemstellung habe ich mir Daten im Frequenzbereich 
generiert und diese dort um 1/2 verschoben.
Die gleiche Verschiebung fuehre ich im Zeitbereich durch und vergleiche 
die Ergebnisse.
Mir ist aufgefallen, dass NUR bei der hoechsten Frequenz (Nyquist) ein 
Fehler auftritt.

Meine eigentliche Anwendung sieht die Verwendung eines Filter-Fensters 
vor. Wende ich dieses Fenster auf die Daten an, tritt ein Fehler in der 
Verschiebung im Zeitbereich auf.

Es folgt der Code, den ich verwende:
1
clear;clc;
2
3
M = 16;
4
m = ([0:M/2 -M/2+1:-1]).';
5
m1 =[0:64/2 -64/2+1:-1].';
6
7
% exp-Term fuer eine Zeit-Verschiebung von 1/2, durchgefuehrt im Frequenzbereich. 
8
shift = exp(1i*2*pi/64.*m1*1/2);
9
10
% Nur die hoechste Frequenz mit Daten belegen, um den Fehler sichtbar zu
11
% machen
12
dataIn = zeros(M,1);
13
dataIn(M/2+1) = 1;
14
15
% Hann-Fenster
16
win    = hann(4*M);
17
% Verschobenes Hann-Fenster, um 1/2 Sample
18
win_sh = ifft(fft(win).*shift);
19
20
figure(1);clf; stem([(0:63).' (0.5:63.5).'],[win win_sh]);legend('win','win _sh');
21
22
beta = exp(1i*2*pi/M.*m*1/2); 
23
sig1 = ifft(dataIn.*beta);
24
sig2 = ifft(dataIn);
25
% % Daten ohne Fenster, es treten keine Probleme auf
26
data1 = [sig1;sig1;sig1;sig1];
27
datax = [sig2;sig2;sig2;sig2];
28
29
% Daten mit Fenster, FEHLER !
30
% data1 = [sig1;sig1;sig1;sig1].*win;
31
% datax = [sig2;sig2;sig2;sig2].*win_sh;
32
33
% Verschiebung der Daten im Zeitbereich
34
data2 = ifft(fft(datax).*shift);
35
36
sum(abs(data1-data2))
37
38
figure(2);clf;
39
subplot(211);stem([(1:length(data1)).' ,(1:length(data2)).'],real([data1 data2 ]));legend('sig1','sig2');title('real part');
40
subplot(212);stem([(1:length(data1)).' ,(1:length(data2)).'],imag([data1 data2 ]));legend('sig1','sig2');title('imag part');

Um den Effekt zu zeigen, verwende ich nur die Nyquist-Frequenz. Die 
Stelle wo der Fehler auftritt laesst sich Einkommentieren!

Hat jemand eine Idee, warum sich das Signal im Zeitbereich nicht mehr 
verschieben laesst, wenn ich ein Fenster anwende? Was genau passiert 
hier mit der Nyquist-Frequenz?

Viele Gruesse

Cotton

: Bearbeitet durch User
von Detlef _. (detlef_a)


Lesenswert?

Ich verstehe Deinen post nicht richtig, ich weiß nicht genau was Du 
willst, insbesondere verstehe ich Deine Fenstergeschichte nicht.

Was ich aber weiß:
Die Nyquist Spektralkomponente eines reellen Signals ist rein reel, 
genauso wie die DC Komponente.
Ich bin nicht ganz sicher, aber ich glaube, dass man ein Signal mit 
Nyquist Spektralkomponenten so nicht im Spektralbereich schieben kann.

Cheers
Detlef

von Detlef _a (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

wenauchimmerdasinteressierenmagaussermir:

Für Signale ohne Nyquist Anteil funktioniert die Verschiebung so wie der 
TO das beschrieben hat: FFT, dann die Frequnzkomponenten linear 
weiterdrehen, zurücktransformieren.

Wenn die Signale einen Nyquist Anteil haben gehts' nicht mehr so. Das 
ist auch anschaulich klar: Für genau Nyquist erwischt man zwei samples 
pro Sinuswelle, die Amplitude geht verloren, die hängt von der 
Phasenlage des Signals zur Abtastfrequenz ab.

Man kann ein Signal mit Nyquistanteil aber sehr wohl subsample genau 
verschieben, indem man im Zeitbereich bleibt und die sinc-Funktion 
(sin(x)/x) heranzieht.

Das angehängte Bild zeigt ein Beispiel: Grün ist eine gewählte Funktion 
mit Nyquist-Anteil, Rot ist dieselbe Funktion ohne Nyquist-Anteil 
(jeweils abwechselnd +1 und -1 addiert). In blau ist die grüne Funktion 
aus fein aufgelösten sinc-Funktionen zusammenaddiert, an den 
Abtastzeitpunkten passt's genau. Wenn man die grüne Funktion jetzt 
subsample verschieben will bewegt man sich auf der blauen Kurve. Bißchen 
gegen die Anschauung: Bei Verschiebung um einen halben Abtastwert bleibt 
die Gerade der grünen Funktion keine Gerade.

Auch der Einheitsimpuls wird bei Verschiebung um einen halben Abtastwert 
zu einem unendlich langen 'sinc-Gezappel', contra-intuitiv.

Das Ganze wirft auch ein wenig Licht auf eine Frage, die mich schon 
lange beschäftigt und zu der ich noch keine Antwort gefunden habe:

Wenn ich ein Signal mit Nyquist Rate abtaste, wie berechne ich dann aus 
den Abtastwerten die Maxima/Minima des Signals?

So ist das
Angehängt der Matlab Code.

Cheers
Detlef

clear

sig=[0:2:6 0:2:6];
%sig=[0 0 0 1 0 0 0 0 ]
sig =sig-mean(sig);
spsig=fft(sig);
spsig(5)=0;
sigr=ifft(spsig);
plot(1:8,sig,'.-',1:8,sigr,'.-')

ni=linspace(1,8,2^12);
erg=zeros(size(ni));
for(k=1:8)
    erg=erg+sig(k)*sinc(ni-k);
end;

plot(ni,erg,1:8,sig,'.-',1:8,sigr,'.-')

return

von Matthias M. (Gast)


Lesenswert?

Hallo!

Das sich im Spektrum etwas verschieben lässt, klingt für mich insofern 
einleuchtend, da wenn die Phasenkomponenten alle gleich viel verschoben 
werden, das ja linearphasing ist und einfach nur einer Verschiebung im 
Zeitbereich (Delay) entspricht.

Wenn das Spektrum über die Nyqist-Frequenz geschoben wird, was sollte da 
eurer Meinung nach passieren?

Das ist doch so wie wenn man es vorne (frequenzmäßig) wieder 
reinschiebt, oder? Und deshalb gibt es eben diesen Fehler bei der 
höchsten Frequenz.


Detlef_a schrieb:
> Wenn die Signale einen Nyquist Anteil haben gehts' nicht mehr so. Das
> ist auch anschaulich klar: Für genau Nyquist erwischt man zwei samples
> pro Sinuswelle, die Amplitude geht verloren, die hängt von der
> Phasenlage des Signals zur Abtastfrequenz ab.

Auch eine interessante Betrachtungsweise. Und stimmt: von 0 bis max. 
Amplitude alles möglich ;-)

LG

von Detlef _a (Gast)


Lesenswert?

Matthias M. schrieb:
> Und deshalb gibt es eben diesen Fehler bei der
> höchsten Frequenz.

Genau. Der Fehler tritt bei der von mir vorgestellten Interpolation mit 
sinc nicht auf.

Cheers
Detlef

von Detlef _a (Gast)


Lesenswert?

So,

fertig, ne schöne Matlab Routine, die Signale mit Nyquist 
Frequenzanteilen um Bruchteile von samples schieben kann. Die 
Interpolation erfolgt mit der sinc-Funktion.

Die entstehende Doppelsumme macht quadratische Laufzeit bezogen auf die 
Signallänge n. Das habe ich allerdings mit einer Investition in 
Nachdenken auf die Faltung mit der Signallänge 2*n reduziert, die 
wesentlich schneller geht.

War Spass jewesen.
math rulez!
Cheers
Detlef

function [erg3]=verschieben(x,d)
%Signal verschieben um d samples,
%d muss nicht ganzzahlig sein;

% Es werden Nullen reingeschoben
%nn=110;
%x=randn(1,1000);
%x=1:8;
x=x(:);
%d=0.5;

n=length(x);

% Laufzeit proportional zu n^2 :-((

%erg=zeros(size(x));
%for k=1:n
%    erg=erg+x(k)*sinc((1:n)-k+d).';
%end

% Laufzeit proportional zu n^2 :-((
%erg1=zeros(size(x));
%for k=1:n
%    erg1(k)=sinc(((1-n):0)+k-1+d)*x(n:-1:1);
%end

% Laufzeit proportional zu n^2 :-((
%xx=[x(n:-1:1); zeros(n,1)];
%yy=sinc(((1-n):(n-1))+d);
%yy=[yy 0];
%yy=[yy yy];
%erg2=zeros(size(x));
%for k=1:n
%    for m=1:(2*n-1)
%    erg2(k)=erg2(k)+yy(k+m-1)*xx(m);
%    end
%end

xxx=[x(n:-1:1); zeros(n,1)].';
yyy=[sinc(((1-n):(n-1))+d) 0];
% Laufzeit proportional zu
% (2*n)*log(2*n) :-)))
erg3=ifft(conj(fft(xxx)).*(fft(yyy)));
erg3=erg3(1:n).';

%sum(abs(erg-erg3))

return

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.