Hilfestellung zu FIR-Filter

Gast #764895
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?
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.
Gast
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
Gast
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
Gast
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?
Gast
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
}
Gast
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.
Gast
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...
Gast
@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
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?!?
Gast
@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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.