www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Berechnung einer exponentiellen Abnahme


Autor: Bjoern B. (minkfeld)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuche gerade eine exponentielle Abnahme eines Wertes zu 
berechnen. Leider soll das ganze auf nem Tiny25 passieren. Da der zu 
wenig Speicher hat,
ist die Berechnung mit der math.h nicht möglich.

Das ganze soll ungefähr diese Form haben:

wert = 150x(0.9)^t

Nun habe ich keine Ahnung wie ich diese Formel anders umsetzen kann. 
Jemand ne Idee?


Gruß Mink

Autor: Kevin K. (nemon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn es nicht so genau sein soll, nimm eine wertetabelle und mach eine 
lineare approximation bei zwischenwerten (oder ist +-*/ erst in der 
math.h enthalten?)

Autor: Thomas Bremer (Firma: Druckerei Beste) (virtupic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da gibt es eine Rekursionsformel:

f(x+1) = t*f(x) = f(x) - (1-t)*f(x)

Schrittweise kanns du variieren für Genauigkeit oder zeitliche 
Auflösung. Aber Vorsicht, Der Faktor ist auch exponentiell in der 
Schrittweite. Also Halbierung heißt von .9 auf sqrt(.9) und Verdoppelung 
der Schrittweite heißt von .9 auf .9*.9 = .81!

Okay, diese Formel hilft nicht bei der Interpolation. Aber um die geht's 
doch hoffentlich nicht. (?)

virtuPIC

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fragen zur Frage:
- Was ist der Wertebereich von t (untere und obere Grenze)?
- Ist t immer ganzahlig?
- Wenn nicht, in welchem Format liegt t vor (Gleitkomma, Festkomma,
  ...)?
- Welches Format und welche Genauigkeit soll das Eregbnis haben,
  reicht Runden auf die nächste ganze Zahl?

Autor: Bjoern B. (minkfeld)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

>wenn es nicht so genau sein soll, nimm eine wertetabelle und mach eine
>lineare approximation bei zwischenwerten

das hatte ich schon versucht, klappt auch bei größeren Werten von t da 
dort nicht so viel Genauigkeit verlangt wird. Bei kleineren Werten von t 
ist das aber ziemlich ungenau. Aber Danke für den Tip.

>Da gibt es eine Rekursionsformel:

>f(x+1) = t*f(x) = f(x) - (1-t)*f(x)

Hab mal versucht darüber was zu finden und es nachzuvollziehen, aber 
irgendwie versteh ich es nicht ganz. Vielleicht kannst du mir das etwas 
genauer erklären?

>Fragen zur Frage:
>- Was ist der Wertebereich von t (untere und obere Grenze)?
>- Ist t immer ganzahlig?
>- Wenn nicht, in welchem Format liegt t vor (Gleitkomma, Festkomma,
>  ...)?
>- Welches Format und welche Genauigkeit soll das Eregbnis haben,
>  reicht Runden auf die nächste ganze Zahl?

Der Wertebereich von t liegt zwischen 1-3000, t ist immer ganzahlig. Das 
Ergebnis soll ganzzahlig zwischen 0-150 liegen. Runden ist kein Problem.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bjoern B. wrote:

> Der Wertebereich von t liegt zwischen 1-3000, t ist immer ganzahlig. Das
> Ergebnis soll ganzzahlig zwischen 0-150 liegen. Runden ist kein Problem.

Dann brauchst Du ja nur ne Tabelle mit 150 Werten (300 Byte) und dann 
einfach 8-mal vergleichen.


Peter

Autor: Bjoern B. (minkfeld)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Dann brauchst Du ja nur ne Tabelle mit 150 Werten (300 Byte) und dann
>einfach 8-mal vergleichen.

Wie 8-mal vergleichen?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

x(t) = a * b^t

x(tk+1) / x(tk) = a*b^tk+1/(a*b^tk)

= b^tk+1 / b^tk = b^(tk+1-tk) = b^t_Abtast

ergo:

x(tk+1) = x(tk) * b^t_Abtast

mit x(0) = a*b

Gruß

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Dann brauchst Du ja nur ne Tabelle mit 150 Werten (300 Byte) und dann
>>einfach 8-mal vergleichen.

>Wie 8-mal vergleichen?

du schaust zuerst ob dein Wert in der oberen oder der unteren Hälfte der 
Tabelle liegt

dann dann das gleiche in der gefundenen Hälfte

usw.

das ganze musst du 8x machen um zum Ziel zu kommen

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für t >= 55 wird das auf ganze Zahlen gerundete Ergebnis 0. Es genügt
also, eine Tabelle tab mit 55 Elementen anzulegen, so dass

  tab[i] = 150 * 0.9**i (gerundet)

ist. Da alle Tabellenwerte kleiner als 256 sind, benötigt man für
jedes Element 1 Byte, für die ganze Tabelle also 55 Bytes. Die
Auswerteroutine ist sehr einfach, ein Suchalgorithmus ist nicht
erforderlich:
unsigned char f(int t) {
  static unsigned char tab[55] = {
    150, 135, 122, 109,  98,  89,  80,  72,  65,  58,
     52,  47,  42,  38,  34,  31,  28,  25,  23,  20,
     18,  16,  15,  13,  12,  11,  10,   9,   8,   7,
      6,   6,   5,   5,   4,   4,   3,   3,   3,   2,
      2,   2,   2,   2,   1,   1,   1,   1,   1,   1,
      1,   1,   1,   1,   1
  };

  return t >= 55 ? 0 : tab[t];
}

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleiner Nachtrag: Da t nicht negativ wird, sollte man das
Funktionsargument als unsigned int deklarieren. Für den gesamten
Wertebereich von unsigned int liefert die Routine ein sinnvolles
Ergebnis, für negative Werte hingegen nicht.

Autor: 6645 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine exponentielle Abnahme bedeutet, dass pro Zeiteinheit ein konstanter 
Faktor subtrahiert wird. Dies laesst sich gut mit Fractionals erreichen

x(n+1) := x(n) - const*(x(n) shr 8)

Autor: Bjoern B. (minkfeld)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah,

jetzt hab ich es kapiert. Werd es gleich mal ausprobieren und später mal 
Meldung geben.


Vielen Dank und Gruß

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
xk+1 = xk * b^t_Abtast
x0   = a*b

Wenn a = 150; b = 0.9; und t_Abtast = 1.0s dann:

x0 = 135

b^t_Abtast = 0,9

Annahme:
x ist 16Bit Festkommazahl mit 256=1,0 und der Faktor ist 16Bit 
Festkommazahl mit 65536=1,0:

x0 = 135*256
b^t_Abtast = 0,9 => Faktor = 58982

16Bit*16Bit Multiplikation liefert 2x16Bit Ergebnis mit

xk+1 = obere 16Bit

Man muss also nur eine (unsigned) 16Bit*16Bit Multiplikation machen und 
hat in den obersten 8Bit das Ergebnis ohne zu Interpolieren.

Gruß

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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