arm_cmplx_mag_q31 Wie wird diese Funktion richtig genutzt?!

Gast #6573521
Ich möchte mit einem STM32F103 den Betrag eines Vektors in einer 
zeitkritischen Routine berechnen.
In den CMSIS libraries gibt es dafür die Funktion arm_cmplx_mag_q31()
https://www.keil.com/pack/doc/CMSIS/DSP/html/group__cmplx__mag.html

Aber wie benutze ich die?! Mit Festkommas bin ich nicht sattelfest :-)
Als Beispiel kann das klassische "Maurerdreieck dienen.
1
q31_t complex_voltage[2] = {3000, 4000};
2
q31_t result[2];
3
arm_cmplx_mag_q31(complex_voltage,result,1);

hier würde ich jetzt als result[0] gerne 5000 rausbekommen.
Leider habe ich keine Beispiele gefunden, die mich zum richtigen 
Ergebnis geführt hätten.

Die Funktion arm_sqrt_q31 habe ich mit diesem Beispiel dazu gebracht, 
sinnvolle Werte zurückzugeben.
https://github.com/DD4WH/Teensy-SDR-Rx/blob/master/AM_demod.cpp

Weiß jemand wie man arm_cmplx_mag_q31 richtig anwendet?

Gruß
hochsitzcola
Die Funktion ist eigentlich ziemlich übersichtlich:
1
 /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */ 
2
    real = *pSrc++; 
3
    imag = *pSrc++; 
4
    acc0 = (q31_t) (((q63_t) real * real) >> 33);   // [1]
5
    acc1 = (q31_t) (((q63_t) imag * imag) >> 33); 
6
    /* store the result in 2.30 format in the destination buffer. */ 
7
    arm_sqrt_q31(acc0 + acc1, pDst++);

Bei Werten von 4000 und 5000 kommt bei der Quadrierung [1] allerdings 
0(Null) heraus.

Abhilfe: Wertebereich vernünftig wählen, d.h. anders skalieren. Zum 
Bleistift die 3000 und die 4000 vorher mit 1024 multiplizieren.
Gast
Jim M. schrieb:

> Bei Werten von 4000 und 5000 kommt bei der Quadrierung [1] allerdings
> 0(Null) heraus.

Nicht bei der Quadrierung, sondern bei der Skalierung der 
Zwischenergebnisse auf FP 4.28...

@TO: die Routine erwartet die Eingabe im 1.31-Festkommaformat und 
liefert das Ergebnis mit FP 2.30, bist du dir dessen bewusst?
Gast
OK, da spuckt also das rightshift 33 in die Suppe. Wenn die 
Eingangswerte groß genug sind, geht es tatsächlich. Da das Ergebnis als 
2.30 berechnet wird, braucht es beim zurückshiften eine Stelle weniger, 
um wieder auf 1.31 zu kommen. So kommt für temp5 auf jeden der 
gewünschte Wert 5000 raus :-)
Vielen Dank!
Komisch finde ich nur, das es keinen Hinweis in der 
Funktionsbeschreibung gibt, daß die Eingangswerte eine mindestgröße 
haben müssen...

1
q31_t complex_voltage[2] = {3000<<10, 4000<<10};
2
q31_t result[2];
3
arm_cmplx_mag_q31(complex_voltage,result,1);
4
temp5=(result[0]>>9)+1;

Gruß
hochsitzcola
Gast
hochsitzcola schrieb:

> Komisch finde ich nur, das es keinen Hinweis in der
> Funktionsbeschreibung gibt, daß die Eingangswerte eine mindestgröße
> haben müssen...

Müssen sie ja auch nicht haben. Alles bis herunter zu 0 funktioniert 
ganz hervorregend und liefert ein Ergebnis, was im Rahmen der lt. Doku 
erwartbaren Genauigkeit korrekt ist.

Die Verfasser der Doku gehen halt davon aus, dass jemand, der 
Fixed-Point-Routinen verwendet, auch in der Lage ist, deren 
Implikationen zu begreifen.

Tatsächlich benutzt du sie ja nicht "as intended", sondern 
zweckentfremded. Das ist OK, solange man weiß, was man tut. Du weißt das 
nicht, also solltest du es lernen. Und zwar, bevor du es tust...

Das hier ist nämlich noch ziemlich einfach zu überschauen. Es gibt 
reichlich Operationen, die nicht so einfach zu verstehen sind. Und auch 
nicht so einfach zweckenentfremded zu benutzen...
Gast
c-hater schrieb:
> Tatsächlich benutzt du sie ja nicht "as intended", sondern
> zweckentfremded. Das ist OK, solange man weiß, was man tut. Du weißt das
> nicht, also solltest du es lernen. Und zwar, bevor du es tust...

wenn die Menschen immer erst alles hätten verstehen wollen, bevor sie es 
getan haben, würden wir wahrscheinlich noch auf den Bäumen hocken :-)
Aber du hast natürlich recht, wenn man etwas verstanden hat, tut man 
sich deutlich leichter in der Anwendung :-)

Gruß
hochsitzcola

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 5 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.