Seite 1 von 2
Logarithmus-Problem...
Verfasst: 13.03.2008 15:13
von ZeHa
Servus,
ich hoffe hier kann mir der ein oder andere weiterhelfen

Wie läuft das, wenn ich z.B. eine logarithmische Skala habe, z.B. den Frequenzbereich von 0 bis 20 kHz, und diesen nun in einem Koordinatensystem anzeigen will?
Nehmen wir an, ich hätte die ganz normale Logarithmus-Kurve, die ja nach rechts immer flacher wird. Nun will ich die so anzeigen, daß sie exakt diagonal ist, also muß ich ja die x-Achse entsprechend logarithmisch skalieren.
Wie kann ich das am einfachsten umsetzen? Wie muß ich die einzelnen Werte skalieren? Was muß ich beachten? Ist das Vorgehen immer gleich, egal ob meine Werte von 0 bis 10 oder von 0 bis 20000 gehen? Wie gehe ich mit Sonderfällen um (z.B. 0 und 1)?
Verfasst: 13.03.2008 15:17
von ZeHa
Ach ja, ich hab schonmal eine Schleife von 0 bis 20000 gemacht, und mir alle Werte mal ausgeben lassen, wenn ich den Zähler in Math.log() einsetze (ich arbeite gerade mit Java, und Math.log() ist der ln).
Diese Werte habe ich dann durch den Maximalwert geteilt (also log(20000)), um nur Werte zwischen 0 und 1 zu kriegen, und diese dann wieder mit 20000 multipliziert. Könnte das evtl. das richtige Vorgehen sein?
Verfasst: 13.03.2008 15:21
von ZeHa
Wenn ich mir das ausgebe, sieht die Kurve schonmal nicht soooo schlecht aus, aber ich habe eben das Problem mit dem Sonderfall bei 0 und 1... und wenn ich nur die Range von 2 bis 20000 nehme, kommt mir als Maximalwert nur ca. 18000 raus und nicht die gewünschte 20000...
Und was mich auch stutzig macht ist der seeehr große Sprung zwischen dem ersten und dem zweiten Punkt... das müßte doch weicher gehen, oder?
So sieht die Kurve aus (vertikal):
Code: Alles auswählen
_____________________________________*
_________________*
______________*
_____________*
____________*
___________*
__________*
_________*
_________*
________*
________*
________*
_______*
_______*
_______*
______*
______*
______*
______*
_____*
_____*
_____*
_____*
_____*
____*
____*
____*
____*
____*
____*
___*
___*
___*
___*
___*
___*
___*
___*
___*
__*
__*
__*
__*
__*
__*
__*
__*
__*
__*
_*
_*
_*
_*
_*
_*
_*
_*
_*
_*
_*
_*
_*
_*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Und das ist der Code:
Code: Alles auswählen
double max = Math.log(20000);
for(int i=2; i<20001; i+=250)
{
int val = (int)(40 - (Math.log(i) / max) * 40);
for(int k=0; k<val; k++)
System.out.print("_");
System.out.println("*");
}
Ich multipliziere jetzt natürlich nur mit 40, damit es gescheit ausgegeben wird. Ist aber nur 'ne Skalierung, von daher unbedeutend...
Verfasst: 13.03.2008 15:48
von STARGÅTE
ich bin etwas verwirrt, was willst du ? ^^
wenn du zB die 2^x Funktion nimmst, und diese auf einfach Logerithmischen Papier aufträgst wird aus der Hyperbeleine Gerade.
Die Einteilung der Achse ist dann nicht in gleichen Abständen :
1, 2, 3, 4, 5...
sondern halt 1,10,100,1000,10000...
damit du weiß wo du nun zB 5 abstägt (was ja nicht genau bei der hälfe zwischen 1 und 10 ist) rechnest du einfach mal kurz LOG10(5) und erhälst 0,698
Das heißt wenn 1 bei 0cm ist und 10 bei 10cm ist 5 bei 7cm.
Hier mal n Beispiel:
Bild
Verfasst: 13.03.2008 16:32
von ZeHa
Also ich formulier es mal ein bißchen anders...
Sagen wir, ich hab ein Array mit 20000 Zahlen, und all diese Zahlen bilden im Endeffekt eine Kurve. Wenn ich diese nun auf dem Bildschirm darstellen möchte, in einer Breite von z.B. 400 Pixeln, dann muß ich einfach nur jeden 50. Wert rauspicken und auf dem Bildschirm darstellen.
Nun möchte ich diese Kurve aber nicht linear, sondern logarithmisch anzeigen, also kann ich nicht einfach jeden 50. Wert nehmen, sondern anfangs muß ich kleinere Schritte machen und am Ende sehr große. Klar soweit? Wenn nicht, bitte diesen Absatz nochmal lesen
Im Endeffekt will ich also die Indizes ausrechnen, die ich brauche, um die einzelnen Werte aus meinem Array zu kriegen, die ich anzeigen muß, damit meine Kurve logarithmisch angezeigt wird.
Vielleicht ist es durch dieses Beispiel etwas klarer geworden...
Verfasst: 13.03.2008 16:42
von STARGÅTE
Du verstehst das falsch, du musst nicht die Definitions-Achse neu Skalieren sondern die Werte-Achse.
Das heißt das du von allen werten im Array einfach den LOG() bildest und dnan aber trotzdem jede 50. Zahlen anzeigst
Verfasst: 13.03.2008 22:00
von Froggerprogger
Man kann jede Achse logarithmisch stauchen. Für die x-Achse hier ein Beispiel:
Um linear aus 20000 Elementen (mit Indizes 0..19999) 400 auszuwählen nimmt man ja einfach jedes 20000/400-ste Element, also 0, 50, 100, 150,....
Um logarithmisch gestaucht auszuwählen, kann man linear im Exponenten mappen. Dazu muss man zunächst neue minimale/maximale Grenzen für den Exponenten definieren z.B. per expMin = 0 und expMax = log10(20000). So kann man nun den minimalen Wert 0 darstellen als 0=10^expMin - 1 und den maximalen Wert als 19999=10^expMax - 1. Um jetzt z.B. 400 daraus auszuwählen, mappt man linear zwischen expMin und expMax und erhält den Wert 'exp'. Den zugehörige Index erhält man über 10^exp - 1, wobei man 'echt' runden sollte. Hier ein Beispiel:
#Size = 20000
; prepare array
Dim A.f(#Size)
For i=0 To #Size-1
A(i) = Log(1+i)
Next
; transform linear mapped indices between 0 and #Size-1 to
; float-indices inside 0 and log(#Size-1) for logarithmic mapping to base 10
; so it is 0 = 10^expMin-1 and #Size-1 = 10^expMax-1
expMin.f = 0
expMax.f = Log10(#Size)
Debug expMax
Debug Pow(10, expMax)
#W = 20
For i=0 To #W-1
; now map 'exp' linear between expMin and expMax to get the index 10^exp - 1 (rounded)
exp.f = (i * (expMax - expMin)) / (#W-1)
index = Pow(10, exp) - 1 ; should be done with additional real round
Debug index
Next
Die Werteachse logarithmisch zu stauchen ist so einfach wie von Stargate beschrieben.
Verfasst: 14.03.2008 00:03
von ZeHa
Okay, vielen Dank schonmal, ich werde mir allerdings nochmal etwas überlegen und morgen schreiben, weil ich hab das Problem daß ich nur sehr schwer erklären kann wo meine Verständnisprobleme liegen. Dennoch, ich glaube die Lösung von Frofferproffer ist ungefähr auch das, was ich machen wollte... aber wie gesagt, ich schreib morgen nochmal genaueres
EDIT: Wie peinlich... hab mich vertippt... sollte natürlich
Froggerprogger heißen und nicht Frofferproffer
Die genaueren Ausführungen kommen noch... hab im Moment grad ein anderes Problem das mehr Priorität hat...
Verfasst: 14.03.2008 16:09
von Sebe
Das ist der Logarithmus bei dem jeder mit muss

Verfasst: 14.03.2008 20:17
von ZeHa
Hmm okay, also mir ging es eigentlich um beides, also sowohl um die x- als auch um die y-Achse, je nach Anwendungszweck also.
Für die x-Achse muß ich also das von Froggerprogger machen, und für die y-Achse das was Stargate sagt, richtig?
Was ich nun nicht ganz verstehe: nehmen wir an ich will die y-Achse stauchen, und ich nehme von jedem Wert, den ich darauf anzeige, einfach den Log-Wert. Dann habe ich keine Ahnung, in welcher Größenordnung sich die Werte befinden werden. Wenn ich das nun auf Werte zwischen 0 und 1 skalieren will, durch welchen Wert muß ich dann teilen? Ich würde jetzt halt den maximalen y-Wert nehmen, davon den Log, und dann durch diesen alle teilen, dann müßten ja alle zwischen 0 und 1 liegen. Oder muß ich das ebenfalls wie bei Froggerproggers Methode machen?
Und was mache ich eben mit den Sonderfällen 0 und 1? Der Log von 0 ist ja -Unendlich...
Oder erübrigt sich das bei Froggerproggers Methode sowieso?