Forum: Digitale Signalverarbeitung / DSP / Machine Learning ARM CMSIS DSPLib: Clippling by mult


von Stephan (Gast)


Lesenswert?

Hey,

ich implementiere z.Zt. eine Funktion, wo ein Datenpuffer mit einem 
anderen multipliziert wird. Die Daten liegen im q15-Format vor und ich 
wundere mich über die Funktion arm_mult_q15 aus der CMSIS DSP-Lib.
Laut der Doku

http://www.keil.com/pack/doc/CMSIS/DSP/html/group___basic_mult.html

ist der Ausgangspuffer auch vom Typ q15; die Werte clippen wenn der 
Wertebereich eines q15 überschritten wird.

Ich erkenne den Sinn darin nicht.
Die Wahrscheinlichkeit dass bei der Multiplikation zweier q15 das 
Ergebnis nicht in einen q15 passt ist doch recht hoch!?

Es existiert keine Implementierung der mult-Funktion für q15-Datenblöcke 
wo das Ergebnis als q31 dargestellt wird.
Ich sehe keine andere Möglichkeit als das händisch mit einer 
for-Schleife zu realisieren.

Wofür ist die Funktion zu gebrauchen?

Stephan

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dürfte ein Feature sein, normale Multiplikationen saturieren in C
ja sonst eher nicht.

Musst du halt vorher q31 aus deinen Daten machen, dafür gibt's ja
Hilfsfunktionen.

von Nils P. (torus)


Lesenswert?

Stephan schrieb:
> Die Wahrscheinlichkeit dass bei der Multiplikation zweier q15 das
> Ergebnis nicht in einen q15 passt ist doch recht hoch!?

Eigentlich nicht.

Bedenke, das die Multiplikation im q15 Format erfolgt, d.h. das Ergebnis 
der Multiplikation wird intern als 32 Bit Wert berechnet und dann wieder 
um 15 Bits nach rechts geschiftet um wieder zu einem q15 Format zu 
gelangen.

In Pseudo-Code sieht das so aus:

  int16_t a = arg1;
  int16_t b = arg2;

  int32_t product = arg1 * (int32_t) arg2;
  int16_t result  = saturate (product>>15, 16);


D.h. das Saturieren ist ehr unwarscheinlich und tritt nur in Fällen auf, 
wo das Ergebniss wirklich nicht mehr in das q15 Format passt. Intern 
läuft alles mit so hoher Genauigkeit das kein Overflow passieren kann.

Caveat: Ob vor dem Shiften sauber gerundet wird oder nicht weis ich 
nicht.

Gruß,
  Nils

von Stefan K. (stefan64)


Lesenswert?


von Stefan K. (stefan64)


Lesenswert?

q15_t bedeutet: 1 Sign-Bit und 15 Nachkomma-Bits. D.h. der Wertebereich 
eines q15_t geht von -1.0 bis 0.99999..

Beim Multiplizieren zweier q15_t passt das Ergebnis immer in ein q15_t: 
zwei Werte kleiner 1 multipliziert ergibt immer ein Ergebnis kleiner 1.

Auf Hardware-Ebene passiert das, was Nils beschrieben hat, 
Multiplikation und anschliessender 15-facher Shift rechts.

Auf Hardwareebene Für die Min/Max-Werte:

0.999 * 0.999  ->  (7FFFh * 7FFFh) >> 15 = 3FFF0001 >> 15 = 7FFE  -> 
0.999
-1.0  * -1.0   ->  (8000h * 8000h) >> 15 = 40000000 >> 15 = 8000  -> 
-1.0


Im oben verlinkten Dokument ist das sehr gut beschrieben.

Viele Grüße, Stefan

von Stephan (Gast)


Lesenswert?

Vielen Dank!

Bzgl. meiner Anwendung:
Wenn ich das richtig interpretiere kann ich also einen Puffer aus
int16-Werten (Zweierkomplement) einfach als q15-Daten übernehmen.
Es ändert sich nur die Interpretation; die Abbildung der Zahlen
+32767 ... -32768 auf den Wertebereich  +1.0-1/2^15 ... -1.0.

Demnach kann ich einen q15-Puffer also einfach mit Daten von einem 
AD-Wandler (liefert Werte in Zweierkomlementdarstellung) füllen, wobei 
dann  die -1.0 einer maximalen Aussteuerung in negative Richtung 
entspricht?

Gruß Stephan

von Stefan K. (stefan64)


Lesenswert?

Kommt auf das Alignment des AD-Wandlers an. Wenn der ADC left-aligned 
speichern kann, dann funktioniert das wie von Dir gewünscht.

Bei einigen ADCs (z.B: der im STM32F) kann man das Alignement 
einstellen. Hat der ADC 16 Bit, dann passt es natürlich immer.

Gruß, Stefan

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.