Forum: Digitale Signalverarbeitung / DSP / Machine Learning Hilfestellung zu FIR-Filter


von Marcel (Gast)


Lesenswert?

Für die Filterung soll folgende Differenzengleichung verwendet werden:

y(k)=x(k)+3x(k-1)+x(k-2)+0.231y(k-1)-0.123y(k-2)

Nun soll man eine C-Funktion schreiben "filter_FIR", die als Parameter 
einen Vector mit Eingangswerten und einen Vektor mit Ausgangswerten 
sowie die Länge der beiden Vektoren bekommt und die Filterung 
durchführt.
1
void filter_FIR(double *x, double *y, int rec)
2
{
3
int n=0;
4
5
for(n;n<rec;n++)
6
   y(n)=x(n)+3x(n-1)+x(n-2)+0.231y(n-1)-0.123y(n-2)
7
}

Stimmt die Umsetzung der Differenzengleichung in die C-Funktion so?

von Daniel D. (bademeister)


Lesenswert?

Abgesehen davon, dass du dem Compiler nicht sagst, dass er vor der 
Klammer ne Multiplikation machen soll, sieht es schon ganz gut aus. Evtl 
könntest du noch den x, bzw y Teil von k-1 zusammenfassen.Ist aber nicht 
nötig, könnte aber eine Multiplikation sparen.

von Gerhard (Gast)


Lesenswert?

Hallo Marcel,

denke so einfach geht das nicht. k in der beschreibenden Gleichung ist 
doch sicher sowas wie die Zeit (zu festen Abtastwerten Delta-T). Das 
heißt für
y(k)=x(k)+3x(k-1)+x(k-2) ...

dass der Ausgangswert y zur Zeit k durch eine Summe von x- und y-Werten 
zur Zeit k, zur Zeit (k-1) (also das Sample davor) und (k-2), also das 
zweitletzte Sample gebildet wird. Hierzu musst du mindestens die 2 
letzten Zeitwerte von x und y zwischenspeichern, um sie in der aktuellen 
Summe parat zu haben (und sie in jedem neuen Zeitschritt auch 
"durchshiften").

Weiteres Problem: Wie startet der Algorithmus. Für das erste Zeitsample 
sind die Felder für (k-1) und (k-2) ja noch leer. Nicht dass das falsch 
ist. Solltest dir aber dessen bewusst sein.

Gruß
Gerhard

von Helmi (Gast)


Lesenswert?

Sieht eigentlich OK aus

void filter_FIR(double *x, double *y, int rec)
{
   int n;
   for(n=0;n<rec;n++)
        y[n]=x[n]+3*x[n-1]+x[n-2]+0.231*y[n-1]-0.123*y[n-2];
}

Bei Arrays wird der Index in [] Klammern gesetzt

Beim Aufruf der Funktion musst du allerdings beachten
das du als Addresse nicht x oder y angibst sondern das ende des Arrays
also x[2] oder y[2] weil du ja in deiner Funktion negative Array werte 
bekommst.

void Test(void)
{
     double  x[3];
     double  y[3];

     filter_FIR(&x[2],&y[2],3);

}

Gruss Helmi

von Marcel (Gast)


Lesenswert?

Recht herzlichen Dank für eure Hilfe.
Noch ein Problem hab ich noch. Und zwar soll nun ein weitere C-Funktion 
mit dem Namen "filter_Forever" implementiert werden, der eine andauernde 
Filterung mit Hilfe der Funktion "filter_FIR" durchführen soll.
Wie kann ich dies machen?

von Marcel (Gast)


Lesenswert?

Dies könnte ich doch dann im Hauptprogramm in einer WHILE Schleife tun.
Bin mir nicht ganz sicher.
1
void main(void)
2
{
3
 double  x[3];
4
 double  y[3];
5
6
 while(1)
7
  {
8
    filter_FIR(&x[2],&y[2],3);
9
  }
10
}

von Helmi (Gast)


Lesenswert?

Könntest du so machen.
Allerdings werden da nirgendwo neue Messdaten eingelesen oder ergebnisse 
ausgegeben.

Gruss Helmi

von Marcel (Gast)


Lesenswert?

Wie würde die C-Funktion "filter_FIR" aussehen, wenn man das ganze mit 
Gedächtnis machen will? Mit Gedächtnis meine ich, dass man nur zum 
Beispiel wenn ein Block 100 lange ist, das nur die ersten 80 Werte 
benutzt werden und die anderen 20 erst beim nächsten durchlauf verwendet 
werden.

von Franz (Gast)


Lesenswert?

Wie wär's mal mit zuhören in der Vorlesung oder den Dozenten fragen, 
wenn man was nicht versteht? Herr Q. ist äusserst hilfsbereit und 
erklärt's auch der letzten Torfnase noch einmal ausführlich. Aber einen 
Tag vor der Klausur natürlich nicht mehr...

von Nils H. (iaby)


Lesenswert?

Stürzt euch das Programm eigentlich nicht ab, da ihr auf ein negativen 
Array Index zugreift?
Beim ersten Durchlauf der Schleife ist n = 0 und ihr addressiert n-1, 
n-2 !

von Helmi (Gast)


Lesenswert?

@Nils H. (iaby)

Das kann nicht abstuerzen weil beim aufruf der Funktion die Addresse vom 
3. Element uebergeben wird.

filter_FIR(&x[2],&y[2],3);

Gruss Helmi

von Nils H. (iaby)


Lesenswert?

Ok stimmt, mein Fehler!
Wenn ich nun aber das 2te Element übergebe und n läuft bis 2, dann greif 
ich ja auf Index 4 zu, das Array hat aber nur 3 Elemente, also Index 
0-2.
Oder steh ich schon wieder auf dem Schlauch?!?

von Helmi (Gast)


Lesenswert?

@Nils H. (iaby)

>Wenn ich nun aber das 2te Element übergebe und n läuft bis 2, dann greif
>ich ja auf Index 4 zu, das Array hat aber nur 3 Elemente, also Index
>0-2.
>Oder steh ich schon wieder auf dem Schlauch?!?

Nein du stehst nicht auf dem Schlauch du hast recht das Array muss
groesser sein.

Gruss Helmi

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.