Forum: Digitale Signalverarbeitung / DSP / Machine Learning Multiplikation führt zu periodischen Peaks/Lücken im Histogramm


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Gustl B. (-gb-)


Lesenswert?

Hallo zusammen,

es gibt ja ein bekanntes Phänomen:

Wenn man viele Werte (alles Integer) aus einem Wertebereich mit einer 
Zahl (Float) > 1 multipliziert (und wieder Integer draus macht), dann 
gibt es im Histogramm des Ergebnis periodische Lücken.

Multipliziert man mit einer Zahl (Float) < 1 so gibt es periodisch 
Peaks.

Der Grund ist, dass der Wertebereich gestreckt bzw. gestaucht wird.
Multiplikation mit > 1 ist also injektiv und nicht surjektiv,
Multiplikation mit < 1 ist surjektiv und nicht injektiv.
(Multiplikation mit 1 ist bijektiv.)

Tja das sieht einfach doof aus wenn man z. B. die Werte eines 
AD-Wandlers betrachtet. Die einzige Lösung die ich bisher kenne ich das 
um ein "LSB" also ±0.5 zu verrauschen.

Gibt es eine bessere Lösung?

: Bearbeitet durch User
von Palle (Gast)


Lesenswert?

Kannst Du uns das mal bitte anschaulich zeigen, aufstelle von Prosa?

von Gustl B. (gustl_b)


Lesenswert?

Ausgangslage ist eine Menge an Werten, Integer.

Werte = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

Das ist ein Histogramm mit 20 Bins die alle die Höhe 1 haben.

Multiplikation:

Ergebnis(i) = int(Werte(i)*Faktor)

Beispiel 1: Faktor = 1.18

Ergebnis = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 20, 
21, 22, 23]

Das Histogramm hat jetzt 23 Bins und periodische Lücken da die Werte 6, 
13 und 19 fehlen.

Beispiel 2: Faktor = 0.83

Ergebnis = [0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 14, 14, 
15, 16]

Das Histogramm hat jetzt 17 Bins und periodische Peaks da die Werte 4, 9 
und 14 häufiger vorhanden sind.

Edit:
Runden bringt hier nichts, das verschiebt nur die Peaks. Beispiel 2 mit 
Rundung sieht so aus:

Ergebnis = [1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 12, 13, 14, 15, 
16, 17]

Das sind weiterhin 17 Bins aber jetzt mit den Peaks bei 2, 7 und 12.

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

Nehmen wir die Multiplikation mit 1,18: du startest mit 20 
gleichverteilten Werten und sortierst diese um auf dem Bereich von 1 bis 
23. dann diskretisierst diese wieder in einser-bins. du verteilst also 
20 Werte auf 23 bins - klar bleiben da Lücken. 20 Werte können nicht 
23bins füllen- was stört dich daran?

wenn du weiter die Gleichverteilung sehen willst musst du weiter 20 bins 
verwenden mit einer Schrittweite von 1,18 (kannst also nicht einfach 
wieder auf Integerwerte runden)

von Gustl B. (gustl_b)


Lesenswert?

Wo das herkommt habe ich verstanden. Was mich daran stört ist, dass wenn 
ich bei einem ADC mit Eingangsschaltung eine Korrektur rechne, digital, 
dann sieht man dahinter diese Lücken oder Peaks im Histogramm der 
Abtastwerte. Klar, könnte ich ignorieren oder eben die Breite der Bins 
mit skalieren, aber sieht eben doof aus, irgendwie kaputt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Gustl B. schrieb:
> Tja das sieht einfach doof aus

Es geht also darum, einen unvermeidlichen Schönheitsfehler zu 
kaschieren?

Dafür gibt es mehrere Möglichkeiten:

1. Das Histogramm gar nicht erst anzeigen

2. Die Werte nach der Multiplikation mit dem Faktor f nicht in Integer 
konvertieren, sondern als Float belassen, und als Intervallbreite der 
Histogrammklassen den Wert f wählen

3. Das Histogramm glätten (gleitenden Mittelwert über die 
Histogrammwerte bilden)

4. Die Balken des Histogramms breiter als die größte zu erwartende Lücke 
zeichnen

5. ...

: Bearbeitet durch Moderator
von Fpgakuechle K. (fpgakuechle) Benutzerseite


Lesenswert?

Gustl B. schrieb:

> Tja das sieht einfach doof aus wenn man z. B. die Werte eines
> AD-Wandlers betrachtet. Die einzige Lösung die ich bisher kenne ich das
> um ein "LSB" also ±0.5 zu verrauschen.
>
> Gibt es eine bessere Lösung?


Man könnte auch beim 'Multiplizieren' (Verstärken) eine Nichtlineare 
(Quantisierungs-) Kennlinie verwenden.

So wird es bei PCM-Sprachübertragung gemacht. Dadurch werden 'Deine 
Lücken' in den Bereich verschoben, die ohnehin nur grob unterschieden 
werden. Also im Bereich der leisen Töne wird genauer quantisiert als im 
Bereich der lauten Töne.

Siehe A-law unf µ-law bei der PCM

https://de.wikipedia.org/wiki/A-law
https://de.wikipedia.org/wiki/%CE%9C-law

: Bearbeitet durch User
von Achim S. (Gast)


Lesenswert?

Gustl B. schrieb:
> eine Korrektur rechne, digital,

wenn du meinst, mit Gleitkommafaktoren skalieren zu müssen, dann musst 
du imho auch die bin-Breite skalieren, wenn du keine Lücken/Peaks sehen 
willst.

von Gustl B. (gustl_b)


Lesenswert?

Yalu X. schrieb:
> Es geht also darum, einen unvermeidlichen Schönheitsfehler zu
> kaschieren?

Das war die eigentliche Frage. Ist das unvermeidlich? Mit meinem 
Matheverständnis ja, aber vielleicht gibt es ja einen Trick den ich 
nicht kenne. Anscheinend nein.

Fpgakuechle K. schrieb:
> Einfach nur ein Histogramm über die Werte aufstellen, die tatsächlich
> vorkommen?!

Das hilft bei Lücken, nicht aber bei Peaks.

Fpgakuechle K. schrieb:
> Man könnte auch beim 'Multiplizieren' (Verstärken) eine Nichtlineare
> (Quantisierungs-) Kennlinie verwenden.

Nein das will ich auch nicht, ich will alle Werte so skalieren, dass z. 
B. 1 V am Eingang dann dem Digitalwert 1024 entspricht.

Klar, ich kann damit leben, nur wollte ich hier eben mal gefragt haben 
denn vielleicht übersehe ich eine mathematisch einfache oder elegante 
Lösung.

Vielen Dank!

von A. S. (achs)


Lesenswert?

Gustl B. schrieb:
> Tja das sieht einfach doof aus wenn man z. B. die Werte eines
> AD-Wandlers betrachtet. Die einzige Lösung die ich bisher kenne ich das
> um ein "LSB" also ±0.5 zu verrauschen.
>
> Gibt es eine bessere Lösung?

Doof in welchem Kontext?

Histogramme fährt man ja i.d.R. auf die unkalibrierten AD-Werte, um auch 
gleich das typische "viele Nullen bevorzugt" zu sehen.

Wenn Du z.B. 1000 Digits auf 1020 oder 980 skalierst, macht ein 
Histogramm wenig Sinn. Es sei denn, Dir ist klar, dass Du 20 Peaks oder 
Leerstellen haben musst und berücksichtigst das.

Durch so ein Beispiel wird auch klar, dass selbst eine Reduktion auf 8 
oder 7 Bit das Problem nicht behebt.

von Thomas W. (dbstw)


Lesenswert?

Moin, -

das Zauberwort heisst Rebinning. Und das Binning eines Histogrammes ist 
schon sehr "interessant", je nach Wahl des Binnings kann man 
verschiedene Aussagen treffen (frag mal einen Physiker).

Versuch mal diesen Blog-Eintrag:

https://www.answerminer.com/blog/binning-guide-ideal-histogram

Gruesse

Th.

von Gustl B. (gustl_b)


Lesenswert?

Achim S. schrieb:
> wenn du meinst, mit Gleitkommafaktoren skalieren zu müssen, dann musst
> du imho auch die bin-Breite skalieren, wenn du keine Lücken/Peaks sehen
> willst.

Da stimme ich dir zu, so habe ich das auch verstanden. Aber es gibt ADCs 
wie den HMCAD1511 die ein einstellbares digitales Gain haben, und 
Gleitkommazahlen. Und wenn ich dessen Abtastwerte nehme und ein 
Histogramm mache sehr ich weder Lücken noch fiese Peaks. Intern sind das 
sogar 8 ADCs die interleaved abtasten und denen kann man 
unterschiedliche digitale Gains geben (digital fine Gain adjust). Auch 
das sieht man nicht im Histogramm der Ausgangswerte. Wird da irgendwie 
getrickst, also die Werte um ein paar LSB verrauscht oder wie macht man 
das?

von Gustl B. (gustl_b)


Lesenswert?

A. S. schrieb:
> Doof in welchem Kontext?
> Histogramme fährt man ja i.d.R. auf die unkalibrierten AD-Werte, um auch
> gleich das typische "viele Nullen bevorzugt" zu sehen.

Doof im Sinne von ich möchte da z. B. Spektren draus bauen bei denen ein 
ADC Wert sagt welche Zerfallsenergie ein Zerfall hatte. Also nur als 
Beispiel. Und da wäre es sehr doof wenn manche Energien häufiger 
vorkommen würden als sie sollten.
Da scheint mit die Lösung mehr Bits mitzunehmen. Oder analog vor dem ADC 
zu korrigieren.

A. S. schrieb:
> Wenn Du z.B. 1000 Digits auf 1020 oder 980 skalierst, macht ein
> Histogramm wenig Sinn. Es sei denn, Dir ist klar, dass Du 20 Peaks oder
> Leerstellen haben musst und berücksichtigst das.
> Durch so ein Beispiel wird auch klar, dass selbst eine Reduktion auf 8
> oder 7 Bit das Problem nicht behebt.

Das ist mir alles klar. Ich hatte nur die Hoffnung, dass es einen Trick 
gibt den ich nicht kenne.

von Gustl B. (gustl_b)


Lesenswert?

Thomas W. schrieb:
> das Zauberwort heisst Rebinning.

Das geht aber nicht in dem Fall. Jeder mögliche Ergebniswert soll einen 
Bin bekommen. Und da ist das Problem, dass bei Faktor < 1 mehr 
Ergebniswerte möglich sind als es ganze Zahlen in dem Bereich gibt. Die 
Bins wären also auch kleiner 1 breit. (Bei Faktor > 1 wären sie > 1 
breit.) Ich will ja nicht die Anzahl der Bins verändern, das ist ein ADC 
mit n Bits also will ich immer 2^n Bins. Da bleibt nur die Breite der 
Bins mit zu skalieren aber das lässt sich dann schlecht plotten. Und 
funktioniert nur wenn man das Ergebnis als Float behält und da keine 
Integer draus macht.

von re (Gast)


Lesenswert?

Die Lücken im Histogramm entstehen, weil Du jeweils den kompletten 
Inhalt eines ursprünglichen Bins vollständig den nächstliegenden neuen 
Bin umfüllst. Der eine der beiden benachbarten neuen Bins geht dabei 
vollständig leer aus, obwohl einige der originalen Messgrößen 
tatsächlich eher in den benachbarten neuen Bin passen würden, als in den 
nächstgelegenen.

Die Information, ob ein einzelner Originalwert eher in den linken oder 
in den rechten neuen Bin gehört, ist aber weg. Man weiß nur noch, in 
welchem der originalen Bins ein Zählereintrag gehört.


Wenn man nun annehmen kann, dass die Messgrößen, die in einem der 
ursprünglichen Bins gezählt wurden, gleichverteilt sind, dann kann man 
das ursprüngliche Bin anteilig auf die benachbarten neuen Bins verteilen 
und die Lücken verschwinden ("Rebinning", wie schon von Thomas W 
erwähnt).

Wenn diese Annahme nicht zutrifft, dann ist das allerdings im besten 
Fall nur pure Kosmetik und im schlimmsten Fall einfach nur falshc, aber 
in vielen Fällen ist das gut plausibel (z.B. "Rauschen").


Für "Peaks" gilt das gleiche.

HTH
(re)

von Achim M. (minifloat)


Lesenswert?

Gustl B. schrieb:
> Gibt es eine bessere Lösung?

Fraktionale Zahlen verwenden.
Dazu zum Beispiel 4 LSB der resultierenden Zahlen wie Nachkommastellen 
verwenden, aber beim Binning nicht bei jedem LSB trennen (so war es ja 
bei deiner Integer-Darstellung).

Das wäre die Light-Lösung zu "ab Multiplikation alles in float". Oder 
gleich alles in fraktionalen Zahlen rechnen.

mfg mf

von Wolfgang (Gast)


Lesenswert?

Gustl B. schrieb:
> Das ist mir alles klar. Ich hatte nur die Hoffnung, dass es einen Trick
> gibt den ich nicht kenne.
Wenn du 20 Ganzzahlintervalle direkt auf 23 Ganzzahlintervalle 
abbildest, hast du zwangsläufig 3 leere Intervalle, weil 20 kleiner als 
23 ist. ;-)

Eigentlich willst du bei der Aufteilung auf Intervalle für ein 
"hübsches" Histogramm nicht Anzahlen darstellen, sondern Anzahldichten. 
Das wäre ein stetiger Wert und für ein Histogramm (Balkenform) würde 
dann die Anzahldichte für die zugehörige Intervallmitte dargestellt. Aus 
deinen diskreten Eingangswerten musst du dazu erstmal eine stetige 
Anzahldichtefunktion erzeugen, die für jede reelle Zahl einen Wert 
liefert.

von Gustl B. (-gb-)


Lesenswert?

re schrieb:
> Die Information, ob ein einzelner Originalwert eher in den linken oder
> in den rechten neuen Bin gehört, ist aber weg. Man weiß nur noch, in
> welchem der originalen Bins ein Zählereintrag gehört.

Naja das ist eben so. Wenn mein ADC 8 Bits hat, dann werden nur 256 
diskrete Werte unterschieden und natürlich fehlt dann bei jedem 
einzelnen Wert die Informaton ob der eher an der Grenze zum oberen oder 
unteren Nachbarn lag. Dazu bräuchte man z. B. Nachkommabits. Habe ich 
nicht, der ADC (hier als Beispiel) liefert nur einen festen begrenzten 
Wertebereich.

re schrieb:
> das ursprüngliche Bin anteilig auf die benachbarten neuen Bins verteilen
> und die Lücken verschwinden ("Rebinning", wie schon von Thomas W
> erwähnt).

Hm, das habe ich noch nicht ganz verstanden?! Ich erkläre mal wie ich 
mir das vorstelle:

Man hat zwei drei nebeneinanderliegende Originalbins der Werte 1, 2 und 
3.
Jetzt kann man bei angenommener Gleichverteilung sagen, dass im Bin 2 
der Wert 2.0 genauso häufig ist wie der Wert 2.9.
Wenn man jetzt also alle Werte mit einem Float multipliziert, dann kann 
man gedanklich jeden Bin weiter unterteilen in noch mehr (im Idealfall 
in infinitesimal viele weil es ist ja eine Fläche jeder Bin (Integral)) 
Bins, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 
... diese alle multiplizieren und dann quasi neu unterteilen in die alte 
Anzahl an Bins.
Ist das korrekt?

von A. S. (achs)


Lesenswert?

Gustl B. schrieb:
> Doof im Sinne von ich möchte da z. B. Spektren draus bauen bei denen ein
> ADC Wert sagt welche Zerfallsenergie ein Zerfall hatte. Also nur als
> Beispiel. Und da wäre es sehr doof wenn manche Energien häufiger
> vorkommen würden als sie sollten.

5 Möglichkeiten (Nullpunkt und Skalenendwert kannst Du ja konstruktiv 
immer sicher erreichen)

 a) leicht unterschiedliche Auflösungen je nach Kalibrierung
 b) Kalibrierung durch aktiven Offset der Referenzspannung
 c) Kalibrierung durch aktive Kalibrierung
 d) Egalisierung durch Eliminierung jeder X-ten Messung in bevorzugten 
Feldern (reine Mathematik: Wenn Wahrscheinlichkeit 10% höher, dann jeden 
11.ten)
 e) Egalisierung durch Ausgleich (Wenn ein Feld rein Rechnerisch 10% des 
Feldes darunter einnimmt, dann jeden 10ten dorthin verschieben und 
getrennt zählen).

Ich sehe jetzt nicht, warum eine Zufallszahl das besser machen sollte. 
Vermutlich ist es mathematisch nicht mal einfacher.

von Gustl B. (-gb-)


Lesenswert?

Achim M. schrieb:
> Fraktionale Zahlen verwenden.

Korrekt, aber: Der Datenpfad wird dann breiter. Das will ich eigentlich 
nicht.

Wolfgang schrieb:
> Wenn du 20 Ganzzahlintervalle direkt auf 23 Ganzzahlintervalle
> abbildest, hast du zwangsläufig 3 leere Intervalle, weil 20 kleiner als
> 23 ist. ;-)

Das hatte ich schon im 1. Post beschrieben, ich weiß schon wieso das so 
ist. Nur kannte ich keine gute Lösung. Rebinning scheint mir einen 
Versuch wert.

Was ich auch noch nicht verstanden habe ist wie das Andere machen. Eben 
z. B. so ADCs wie der HMCAD1511. Da gibt es ein einstellbares digitales 
fine Gain und trotzdem kommen da 8 Bit Abtastwerte raus die im 
Histogramm weder Spike noch Lücken enthalten.

von A. S. (achs)


Lesenswert?

Korrektur: c) Kalibrierung durch Anpassung der Verstärkung

von Gustl B. (-gb-)


Lesenswert?

A. S. schrieb:
> 5 Möglichkeiten (Nullpunkt und Skalenendwert kannst Du ja konstruktiv
> immer sicher erreichen)

Danke, Manches könnte ich machen, Anderes nicht.

A. S. schrieb:
> Ich sehe jetzt nicht, warum eine Zufallszahl das besser machen sollte.

Natürlich nicht. Daher habe ich das bisher auch nicht gemacht.

von Sigi (Gast)


Lesenswert?

Dein Problem tritt ja nicht nur bei Histogrammen auf,
viele andere Bereiche haben ja gleiche/ähnliche Probleme
(z.B. beim Texturemapping einer GraKa etc.).

Wenn du es schaffst, dein "sauberes" Histogramm mit
"sauberen" Bins (z.B. ganzzahlig) mit geeigneten
Funktionen zu approximieren, dann kannst du an
beliebigen Stellen bzw. Bereichen die Werte für
belibige Bins ausrechnen. Stell dir z.B. ein lineares
Histogramm vor. Einfaches Umskalieren ergibt wieder
ein Lineares Histogramm, sofern die Bins alle gleich
gross sind (unterschiedliche Grössen entlinearisieren!).

Als Funktionsbasis kannst du z.B. quadratische oder
kubische Polynome über je 2 bis 5 Punkten nehmen, ist
nicht so schwer.

von Gustl B. (-gb-)


Lesenswert?

Sigi schrieb:
> Als Funktionsbasis kannst du z.B. quadratische oder
> kubische Polynome über je 2 bis 5 Punkten nehmen, ist
> nicht so schwer.

Ich weiß nicht ob das der richtige Weg ist. Ein Bin im Histogramm ist ja 
eigentlich eine Fläche. Also der hat eine Breite und eine Höhe. Und da 
würde ich dann eher diese Fläche nehmen und deren Breite skalieren. Dann 
verändert sich auch die Höhe, klar.

Vorgehen wäre also:
Die einzelnen Bins strecken, Beispiel Faktor 0.94:
Die Bins 0, 1, 2, 3 haben die Grenzen
0.0 ... 1.0 ... 2.0 ... 3.0 ... 4.0

Daraus werden dann die Grenzen
0.0 ... 0.94 ... 1.88 ... 2.82 ... 3.76

Dann wird das wieder unterteilt in 4 Bins der Breite 1.0:

Bin 0 = alter Bin 0 + 0.06* alter Bin 1
Bin 1 = 0.94* alter Bin 1 + 0.12* alter Bin 2
Bin 2 = 0.88* alter Bin 2 + 0.18* alter Bin 3
Bin 3 = 0.76* alter Bin 3

Geht natürlich nur wenn man annimmt, dass die Werte innerhalb eines Bins 
gleichverteilt sind.

: Bearbeitet durch User
von Sigi (Gast)


Lesenswert?

Gustl B. schrieb:
> Ich weiß nicht ob das der richtige Weg ist. Ein Bin im Histogramm ist ja
> eigentlich eine Fläche. Also der hat eine Breite und eine Höhe. Und da
> würde ich dann eher diese Fläche nehmen und deren Breite skalieren. Dann
> verändert sich auch die Höhe, klar.

Ja, genau. Eine Box wird dann durch einen Wert der
approximierenden (oder auch interpolierenden) Funktion
repräsentiert. Beim Rebinnen werden z.B. zwei benachbarte
Boxen "zerschnitten" und die benachbarten Schnittstücke
wieder zusammengesetzt. Und hier ist deine Annahme

Gustl B. schrieb:
> Geht natürlich nur wenn man annimmt, dass die Werte innerhalb eines Bins
> gleichverteilt sind.

kein schlechter Ansatz (man kann natürlich nichtlineare
Annahmen aus den Grössenverhältnissen benachbarter Boxen
machen).

Wenn du also mittels "meiner" Funktionen ein  Rebinning
machst, dann muss das "neue" Boxenvolumen (Breite*Höhe)
gleich dem Funtionenwert an einer Stelle sein (z.B. Bin-Mitte).

von re (Gast)


Lesenswert?

Gustl B. schrieb:
> und dann quasi neu unterteilen in die alte Anzahl an Bins.
> Ist das korrekt?

So ungefähr. Geht aber viel einfacher:

(1) Beispiel: Du hast den Bin "2", der die Messwerte [2.0 .. 2.999] 
beinhaltet.  Da seien jetzt mal 100 gezählte Messwerte drin.

(2) Nun z.B. Multiplikation mit 1.3333: Nach alter Methode würde der 
Bereich ("1","2","3") auf ("1","2","4") abgebiltet werden( mit "3" als 
Lücke).

(3) Tatsächlich transformieren sich die alten Bin-Grenze zu [2.667 .. 
4.000]. Ein viertel der Messwerte (also 25) gehen nun in den Bin "2" 
[2.666 .. 2.999] und die übrigen drei viertel (also 75) zu Bin "3" [3.0 
.. 3.999].

(4) Wenn der alte Bin "1" auch 100 Zähler gehabt hätte, dann würde sich 
der je zur Häfte (also je 50) auf die neuen Bins "1" [1.333 .. 1.999] 
und "2" [2.0 .. 2.666] verteilen. Zusammen mit dem Inhalt aus Schritt 
(3) hat also auch Bin "2" nun 75 Zähler. Bin "3" auch, keine Lücke.

(5) Für die übrigen Bins entsprechend.


Das macht aber, wohlgemerkt, nur dann Sinn, wenn man Gleichverteilung 
innerhalb der Bins unterstellen kann (was hier vermutliuch aber gegeben 
ist).

(re)

von Achim M. (minifloat)


Lesenswert?

Gustl B. schrieb:
> Korrekt, aber: Der Datenpfad wird dann breiter.

Wieviel 16bit- oder 32bit-Maschine?
Wie viele Bits hat der ADC?

mfg mf

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Gustl B. schrieb:
> Was ich auch noch nicht verstanden habe ist wie das Andere machen. Eben
> z. B. so ADCs wie der HMCAD1511. Da gibt es ein einstellbares digitales
> fine Gain und trotzdem kommen da 8 Bit Abtastwerte raus die im
> Histogramm weder Spike noch Lücken enthalten.

Der HMCAD1511 hat intern eine höhere Auflösung, so dass bei der
digitalen Multiplikation mit einem Faktor von bis zu 32 keine Lücken
entstehen (s. Datenblatt). Vermutlich handelt es sich bei bei den
internen ADCs um nichtlineare Flash-ADCs mit ca. 500 Stufen

von A. S. (achs)


Lesenswert?

re schrieb:
> (1) Beispiel: Du hast den Bin "2", der die Messwerte [2.0 .. 2.999]
> beinhaltet.  Da seien jetzt mal 100 gezählte Messwerte drin.

was meinst Du mit Messwert 2.0..2.999? Mache doch das Beispiel mit 
Werten von 1..12, die auf 1..10 umgebint werden sollen.

von re (Gast)


Lesenswert?

Gustl B. schrieb:
> Jetzt kann man bei angenommener Gleichverteilung sagen, dass im Bin 2
> der Wert 2.0 genauso häufig ist wie der Wert 2.9.

A. S. schrieb:
> re schrieb:
>> (1) Beispiel: Du hast den Bin "2", der die Messwerte [2.0 .. 2.999]
>> beinhaltet.  Da seien jetzt mal 100 gezählte Messwerte drin.
>
> was meinst Du mit Messwert 2.0..2.999?


Damit habe ich die Rekapitulation des TO (Gustk B.) bestätigt. Nämlich 
dass für sein Beispiel in dem Bin, den er mit "2" bezeichnet, alle 
Messwerte versammelt sein mögen, die im rechts-halboffenen Intervall 
[2.0 ; 3.0) liegen und wir somit das gleiche meinen. Die '2.999' sollten 
da formloserweise (etwas flapsig, sorry) eine Grenze andeuten, die die 
3.0 gerade ausschließt.

Wenn der ADC des TO also z.B. pro Quantisierungsstufe z.B. 1mV auflösen 
und abwärts runden würde, dann würden in diesem Bin alle Messungen 
gezählt, die eine tatsächliche Messgröße zwischen 2.0mV und "fast 3.0mV" 
haben. Mithin alle Messungen, für die der ADC die Ganzzahl "2" ausgibt.

HTH
(re)

von A. S. (achs)


Lesenswert?

re schrieb:
> Damit habe ich die Rekapitulation des TO (Gustk B.) bestätigt. N

Ah, OK. Also die "Gleitkomma-Bereiche" nur zur Veranschaulichung der 
Transformation. Und in mV, sonst hätte ich [1.5..2.5[ für 2 erwartet.

Danke, alles klar.

von Gustl B. (-gb-)


Lesenswert?

Achim M. schrieb:
> Wieviel 16bit- oder 32bit-Maschine?
> Wie viele Bits hat der ADC?

Welche Maschine? Das ist erstmal nur Theorie.

Yalu X. schrieb:
> Der HMCAD1511 hat intern eine höhere Auflösung, so dass bei der
> digitalen Multiplikation mit einem Faktor von bis zu 32 keine Lücken
> entstehen (s. Datenblatt).

Ich weiß. Trotzdem würde mich interessieren wie das dort gemacht wird.
Wobei, vielleicht sind gerade die mehr Bits der "Trick".
Dieser ADC gibt 8 Bits aus je Abtastwert. Sagen wir intern wird mit 12 
Bit gearbeitet.
Nach einer Multiplikation hat man also Lücken oder Peaks im Histogramm 
der 12 Bit Werte. Aber wenn man die LSBs wieder abschneidet und da nur 
die 8 MSBs nimmt, dann werden jeweils 16 Werte auf einen Wert 
abgebildet. Eine Lücke oder ein Peak würde dann nur noch mit 1/16 der 
"Auffälligkeit" im 8-Bit Histogramm auffallen.

A. S. schrieb:
> Und in mV, sonst hätte ich [1.5..2.5[ für 2 erwartet.

Ja ich wollte damit die Thematik der Null umgehen. Geht die dann von [0 
... 0.5[ ? Das wäre dann ja nur die halbe Breite. Ob das mV sind oder 
was Anderes ist erstmal egal, mir geht es rein um die Theorie.

von Achim M. (minifloat)


Lesenswert?

Gustl B. schrieb:
> Aber wenn man die LSBs wieder abschneidet und da nur die 8 MSBs nimmt,
> dann werden jeweils 16 Werte auf einen Wert abgebildet. Eine Lücke oder
> ein Peak würde dann nur noch mit 1/16 der "Auffälligkeit" im 8-Bit
> Histogramm auffallen.

Genau so meinte ich das auch.
Beispiel
• 8bit ADC
• 16bit Maschine
• Q12.4 Format

Die rohen ADC-counts erstmal um 4 nach links schieben. Die entstandenen 
fractional Bits mit den 4 MSBs des rohen ADC füllen, damit man einen 
echten Full-scale des eigentlich 12Bit-Bereichs hat.

Fraktional Multiplizieren.

Dann 8 saturierend addieren und 4 nach rechts schieben, um kaufmännisch 
gerundet wieder auf 8Bit zu kommen.

Dann kommt das Binning und die Anzeige.

Wohl dem der eine FPU hat, ....
mfg mf

edit: Handy-Formatierung nervt.

: Bearbeitet durch User
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Achim M. schrieb:
> Die entstandenen
> fractional Bits mit den 4 MSBs des rohen ADC füllen, damit man einen
> echten Full-scale des eigentlich 12Bit-Bereichs hat.

Exakt, aber: Man muss sie mit Rauschen füllen.

Ich habe das mal in Python getestet.
1. Liste gebaut die alle Werte von 0 ... 1023 jeweils 100 mal enthält.
2. Den Integerwerten noch 6 Nachkommastellen gegeben.
3. a) Die LSBs leer gelassen.
   b) Die LSBs mit Rauschen gefüllt.
4. Die Werte einzeln mit dem Faktor 0.935 multipliziert.
5. Werte zu Integern gemacht, truncated.
6. Histogramm gebaut.

Orange: LSBs leer gelassen
Blau: LSBs mit Rauschen gefüllt

Achim M. schrieb:
> Dann 8 saturierend addieren und 4 nach rechts schieben, um kaufmännisch
> gerundet wieder auf 8Bit zu kommen.

Das habe ich nicht ganz verstanden. +8 bedeutet bei Q12.4 doch nur ein 
+0.5. Wenn ich die LSBs leer lasse (oder ihnen immer den gleichen festen 
Wert gebe) dann bringt das nichts, es verschiebt nur die Spikes/Lücken 
im Histogramm. Und wenn ich aber die LSBs mit Rauschen fülle, dann sehe 
ich den Sinn der Addition von 0.5 nicht.

von A. S. (achs)


Lesenswert?

Gustl B. schrieb:
> Exakt, aber: Man muss sie mit Rauschen füllen.

Und warum nicht abzählen? Dann wären die Werte auf 1 perfekt.

Also bei 2/3 zu 1/3 halt 2 von 3  in das eine, 1 von 3 in das andere 
Feld.

Rauschen hat nur den Vorteil, dass man sich mit der Mathematik nicht 
befassen muss.

von Gustl B. (-gb-)


Lesenswert?

Wie meinst du das mit Abzählen?

Der ADC liefert mir einfach eine Wertefolge, quasi den Integer Anteil. 
Das erweitere ich um ein paar LSBs. Wenn ich jetzt bei jedem Abtastwert 
den gleichen Nachkommawert anhänge, dann habe ich wieder Abtastwerte die 
zueinander immer den gleichen Abstand - 1 - haben.

Ja, ich könnte einen überlaufenden Zähler nehmen der so breit ist die 
ich Nachkommabits habe. Den zähle ich mit jedem Abtastwert hoch und 
hänge den Zählerstand als Nachkommabits an. Meinst du das?

Da könnten vielleicht irgendwelche komisch-periodischen Sachen 
auftreten. Beispiel:

Der ADC tastet ein 62.5 kHz Signal mit 1 MSample/s ab und ich verwende 4 
Nachkommabits. Dann passt das genau zusammen. Idealerweise teffen dann 
immer gleiche Abtastwerte auf gleiche Zählerwerte.
Keine Ahnung ob das in der Realität ein Problem ist, ich vermute nicht, 
aber wieso nicht ein langes LFSR nehmen?

von Achim M. (minifloat)


Lesenswert?

Die LSBs mit MSBs gefüllt hast du nicht probiert? Damit wird der 
ursprüngliche Zahlenbereich auf den Zielzahlenbereich gestreckt.

Das eigentliche Problem ist, dass du je Bin einen Fangbereich von n bis 
m LSBs hast. Dabei sind n und m 1 und 2. Klar dass das auffällt. Wie 
wäre es mit breiteren Bins, statt dir das Histogramm kaputt rauschen zu 
müssen? Dann ergibt nämlich das kaufmännisch Runden einen Sinn...

Die für dich perfekte Lösung besteht wohl darin, die Bins mit 1/0,935 
skalieren Bin-Grenzen zu beschriften ;)

mfg mf

von Gustl B. (-gb-)


Lesenswert?

Achim M. schrieb:
> Die LSBs mit MSBs gefüllt hast du nicht probiert?

Nein, habe ich noch nicht.

Achim M. schrieb:
> Das eigentliche Problem ist, dass du je Bin einen Fangbereich von n bis
> m LSBs hast. Dabei sind n und m 1 und 2. Klar dass das auffällt.

Das habe ich nicht verstanden.

Achim M. schrieb:
> Die für dich perfekte Lösung besteht wohl darin, die Bins mit 1/0,935
> skalieren Bin-Grenzen zu beschriften ;)

Ja, für die Optik ja, aber eigentlich will ich schon Abtastwerte die 
nicht an manchen Stellen häufiger oder seltener vorkommen.

von Achim M. (minifloat)


Lesenswert?

Gustl B. schrieb:
> Achim M. schrieb:
>
>> Das eigentliche Problem ist, dass du je Bin einen Fangbereich von n bis
>> m LSBs hast. Dabei sind n und m 1 und 2. Klar dass das auffällt.
>
> Das habe ich nicht verstanden.

Also. Du hast 1024 Counts ("LSBs") eingehend und (Faktor 0,935) 957 Bins 
ausgehend. Klar dass manche benachbarte Eingangswerte auf einen 
Ausgangswert gemappt sind, manchmal eine 1:1 Beziehung vorliegt.

Gustl B. schrieb:
> Ja, für die Optik ja, aber eigentlich will ich schon Abtastwerte die
> nicht an manchen Stellen häufiger oder seltener vorkommen.

Tun sie ja gar nicht, wenn du die Multiplikation weg lassen würdest.

Oder anders gesagt,
* die Auflösung der Bin-Grenzen passt nicht zur Anzahl der Bins.
* die Bins trennen zu fein auf.
* die Eingangsauflösung ist nicht ausreichend

mfg mf

: Bearbeitet durch User
von A. S. (achs)


Lesenswert?

Gustl B. schrieb:
> Wie meinst du das mit Abzählen?


Gustl B. schrieb:
> Die Werte einzeln mit dem Faktor 0.935 multipliziert.

statt Multiplizieren eine Beschreibung, wo welche Werte einzusortieren 
sind (leider in C)
1
#define N 5 /* wieviel Ziel-Spalten ein Rohwert umspannen kann */
2
struct sZ
3
{ 
4
   int target_start; /* Start-Zielwert (z.B. 0 für ADC-Wert 1) */
5
   int n;            /* wieviele benutzt werden, hier bis zu 2 */
6
   int anteil[N];    /* Anteil in %, wie oft der erste, zweite, ... Wert gefüllt wird */
7
   int cnt[N];       /* Beim Füllen der Hauptwert 0, die anderen siehe unten */   
8
};
9
10
struct sZ Z[1024];
11
12
int histcol(int value)
13
{
14
int i,k;
15
struct sZ *z;
16
int cnt_min;
17
int insert=-1;
18
   
19
   /* Test ob im Range und wähle Beschreibung Z */
20
   ...
21
   z=&Z[value];
22
23
   /* finde minimalen cnt */
24
   for(i=0, cnt_min=1000, k=-1; i<z->n; i++)
25
   { 
26
      if(z->cnt[i] < cnt_min) {cnt_min=z->cnt[i]; k=i;}
27
   }
28
   ASSERT(k>=0);
29
   /* setzte den zu 0 und nivelliere die anderen */
30
   for(i=0; i<z->n; i++)
31
   { 
32
      z->cnt[i]-=cnt_min;
33
   }
34
   /* erhöhe cnt mit der "Wahrscheinlichkeit" */
35
   z->cnt[k]+=100-z->anteil[k];
36
   return z->target_start + k;
37
}
Startwert für cnt: jeder Wert mit (100-anteil)/2 gefüllt und dann auf 0 
nivelliert.

Ja, man könnte noch einen "Kurzschluss" einbauen: Bei z->n=1 ist keine 
Rechnung erforderlich.

Ja, das füllen der Struktur Z erfordert einmal Aufwand, mit 
Gleitkomma-Rechnungen und Rundungen. Das möchte ich hier nicht so 
runterschreiben. Auf der anderen Seite kann dabei auch eine beliebige 
Linearisierung erfolgen.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Achim M. schrieb:
> Klar dass manche benachbarte Eingangswerte auf einen
> Ausgangswert gemappt sind, manchmal eine 1:1 Beziehung vorliegt.

Ja, das ist mir klar, hatte ich im 1. Post oben beschrieben.

Achim M. schrieb:
> Tun sie ja gar nicht, wenn du die Multiplikation weg lassen würdest.

Na das will ich aber nicht. Ich bekomme im Beispiel 8 Bit Werte rein, 
will die mit einem Float multiplizieren und dann wieder als 8 Bit Werte 
ausgeben. Und das möglichst so, dass ein Histogramm dieser Werte weder 
Peaks noch Lücken drinnen hat.

Achim M. schrieb:
> Oder anders gesagt,
> * die Auflösung der Bin-Grenzen passt nicht zur Anzahl der Bins.
> * die Bins trennen zu fein auf.
> * die Eingangsauflösung ist nicht ausreichend

Genau so ist das. Eine perfekte Lösung ist also nicht möglich. Aber man 
kann das so bauen, dass es aus meiner Sicht vertretbar gut ist.

von Achim M. (minifloat)


Lesenswert?

Gustl B. schrieb:
> Aber man kann das so bauen, dass es aus meiner Sicht vertretbar gut ist.

Na dann möchte ich auch wissen, wo du das einsetzen wirst 8)

mfg mf

von Gustl B. (gustl_b)


Lesenswert?

Eine Beispielanwendung hatte ich doch genannt. AD Wandler mit 
feingranularer digitaler Verstärkung. Gibt es, kann man kaufen, will man 
vielleicht auch selber bauen in Hardware.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.