Forum: Compiler & IDEs e_funktion ohne Floating unit rechnen


von Peter (Gast)


Lesenswert?

Hallo an alle

Habe folgendes problem
Muss x= e^(-t/Tau) berechnen auf einem Mikro.
Und habe aber keine floating point unit zur verfügung
kleine info (-t/Tau) liegen im bereich zwischen ~-0.1 und ~-0.005
also -100 [mikro s] bzw 5[mikro s]
Als ergebniss hätte ich gerne ein wert der in etwa so aussieht

x= 123 /* Wert mal 10^-3 */

Diese zahlen sind nur Sinnbildlich.

Benutzen kann ich von u/sint8 bis u/sint32 alles

Hat einer eine Idee wie da vorgehen kann?

Habe Überlegt es durch eine näherung zu versuchen

E X^n/n! kam aber aus laufzeitgründen auf nicht ausrichende ergebnisse

Wäre Super wenn einer eine Idee hat

von Ideen (Gast)


Lesenswert?

Wenn -t und Tau bzw -t/Tau in der Realität der Anlage nur eine kleine 
Anzahl endlicher Werte annehmen kann, beziehungsweise keine allzu hohen 
Anforderungen an die Genauigkeit gestellt werden, kann man immer mit 
vorgefertigten Tabellen arbeiten. Geht am schnellsten braucht aber auch 
am meisten Speicherplatz.

von Peter (Gast)


Lesenswert?

hi danke für die rasche antworte

die überlegnung der Arbeit mit lookup tabels ist auch schon da,

da aber tau  stark schwankt wegen erwärmung der bauteile und t auch 
nicht konstant ist wird es vermutlich ein riesen brocken an tabelle 
geben der dann mit ausreichender genauigkeit in einem bereich von ca 
1-2k Ram liegen wird und dass leider nicht passt fällt diese lösung 
ERSTMAL weg.

Wenn sich natürlich keine andere möglichkeit bietet muss ich sowas 
verwenden und dann deutlich an genauigkeit einbüßen.

Die frage stellt sich ob es eine Lösung gibt bei der durch shiften, 
multiplikationen .... auf einen etwa genauen wert kommen kann.

von Ideen (Gast)


Lesenswert?

> da aber tau  stark schwankt wegen erwärmung der bauteile und t auch
> nicht konstant ist wird es vermutlich ein riesen brocken an tabelle
> geben der dann mit ausreichender genauigkeit in einem bereich von ca
> 1-2k Ram liegen wird und dass leider nicht passt fällt diese lösung
> ERSTMAL weg.

Je nach Controller kann man solche Tabellen auch im 
Programmflash,internen EEPROM oder einem externen EEPROM/Flash ablegen.

von Peter (Gast)


Lesenswert?

Kann ich leider nicht
)-:

Da es sich um ein größeres Projekt handelt und diese berechnung nur ein 
bestandteil einer funktion sein soll bietet sich diese möglichkeit mit 
gewünschter genauigkeit aufgrund plattzmangels leider nicht an. extern 
kann ich leidern gar nichts machen.

von Decius (Gast)


Lesenswert?

Welchen Näherungs-Algorithmus hast Du benutzt ?

von Peter (Gast)


Lesenswert?

Ich habe die Folgende Formel genutzt

unendlich
   E (x^k)/k!
  k=0


Da diese Formel aber Sehr Laufzeitintensiv ist, wird es schwerig damit 
auf ein gutes ergebnis in ausreichender zeit zu kommen.

von Peter (Gast)


Lesenswert?

wenn ich dabei k sagen wir auf 10 setzte sind schon große laufzeiten
vorhanden die dann dazu führen dass andere interrupts entwedere die 
berechnugen unterbrechen oder gar nicht aufgerufen werden während 
dessen.

von Decius (Gast)


Lesenswert?

1. Möglichkeit  unvollständige Tabellen:
weniger Speicherplatz; aber ungenauer
--> Genauigkeit kann durch lineare Interpolation zwischen 2 Werten 
verbessert werden

2. Offline ein Polynom durch Polynominterpolation berechnen (z.B. 
Newtonsche Interpolation, Langrange Interpolation, Taylerpolynom) mit 
möglichst wenigen Stützstellen dabei arbeiten, vermindert der 
Rechenaufwand. Am besten benutzt man dafür so ein Programm wie Mupad 
oder Oktave.

Online Funktionswerte des Polynoms mit Hilfe des Hornerschemas 
berechnen.
--> Genau aber langsamer

3. Mitelweg wäre der CORDIC Algorithmus. Interpolationsalgorithmus, 
kommt in der Regel mit 15 Durchläufen aus. Benutzt im Kern nur 
Additionen, Subtraktionen und Schiebebefehle. Ist nicht nur andwendbar 
bei Winkelfunktionen sondern auch zur Berechnung der e-Funktion.
--> eine gute erreichbare Genauigkeit; mittelschnell

von Decius (Gast)


Lesenswert?

Und nur mit Integerwerten arbeiten!!!

Vermute du hast float benutzt. Dann werden auf einem Mikrocontroller 
ohne Gleitkommaeinheit, alle Floatberechnungen in Software nachgebildet. 
Das ist dann langsam.

von Peter (Gast)


Lesenswert?

Dankeschön

erstmal werde mich mal an option 3 versuchen und mir die laufzeiten 
betrachten. Ansonsten wähle ich option 1.

von Peter (Gast)


Lesenswert?

nein habe kein float genutzt.
Habe x durch division umskaliert damit es passt (-;

Danke für die tipps

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Potenzreihen sind nicht sonderlich gut geeignet für sowas weil man 
schnell Überläufe aus dem Wertebereich bekommt auch wenn der Endwert im 
Rechenbereich liegt.

Beispiel: exp(-10) ≈ 0, hier werden die Summanden x^k/k! in der 
Reihenentwicklung recht groß und neben dem Überlauf-Problem handelt man 
sich noch Ungenauigkeit durch Auslöschung ein.
http://de.wikipedia.org/wiki/Auslöschung_(numerische_Mathematik%29

Das Überlauf-Problem bekommt man in den Griff, indem man ein Polynam 
anders darstellt und auswertet, zB zur Basis von Bernsteinpolynomen. Im 
Endeffekt führt das zu Bézierkurven, die besser bekannt sein dürften.

Für exp(-t), t \in {0, 4/3}

Kann man die Funktion zB so berechnen:
1
#include <stdio.h>
2
#include <math.h>
3
4
double y[] = { 1, 0.56, 0.385, 0.2636 };
5
6
double castelj (double t0)
7
{
8
    double t = t0*3.0/4.0; // t in {0,1}
9
    
10
    double y00 = y[0] + t * (y[1] - y[0]);
11
    double y01 = y[1] + t * (y[2] - y[1]);
12
    double y02 = y[2] + t * (y[3] - y[2]);
13
14
    double y10 = y00 + t * (y01 - y00);
15
    double y11 = y01 + t * (y02 - y01);
16
17
    double y20 = y10 + t * (y11 - y10);
18
19
    printf ("y[%f] = %f, %f\n", t0, y20, exp(-t0)-y20);
20
}
21
22
int main()
23
{
24
    castelj (0);
25
    castelj (0.25);
26
    castelj (0.5);
27
    castelj (0.75);
28
    castelj (1);
29
    castelj (1.25);
30
    castelj (4.0/3.0);

Die Ausgabe des Programms ist
1
y[0.000000] = 1.000000, 0.000000
2
y[0.250000] = 0.779056, -0.000255
3
y[0.500000] = 0.605649, 0.000882
4
y[0.750000] = 0.471418, 0.000948
5
y[1.000000] = 0.368003, -0.000124
6
y[1.250000] = 0.287042, -0.000537
7
y[1.333333] = 0.263600, -0.000003

Am interessantesten hier ist die letzte Spalte, die den absoluten Fehler 
der Näherung vom Grade 3 zu exp(-t) angibt.

Wichtig sind eigentlich nur die Auswertung (kein Hornerschema etc!) 
und die Konstanten y[].

Die Umstellung auf Festpunkt-Arithmetik ist dann nur noch ein bisschen 
Technik :-)

von Matthias L. (Gast)


Lesenswert?

>Muss x= e^(-t/Tau)

Das ist doch die klassische Ausgleichskurve.
Vielleicht bringts ja was, wenn du nur ein paar Daten als Lookup 
ablegst.
Etwa sowas:
1
t/T in 0.1 |   0       1    2    ...    10    ...    20   ....   30   ....   40  ....   50
2
-----------+------------------------------------------------------------------------------
3
x          |   100    90   82           37           14           5           2          0
Also das Verhältnis -t/T und das Ergebnis, skaliert in 10tel, oder in 
256stel zB.

Hm...

von Peter (Gast)


Lesenswert?

Hi @all

Danke für die Felißige hilfe

habe es ganz einfach gemacht

habe mir Überlegt welche x Werte vorkommen können und habe dann dies in 
kleinere schritte aufgeteilt. Dann habe ich dass ganze in eine 
Lookuptabelle gelegt und einen algorithmus zugefügt der für den 
gewünschten x wert den mittleren aus x-1 und x+1 (welche festgelegt 
wurden) bestimmt.
In einem bereich von    -4 < x < 0 und 0,1 schrittweite bin ich sehr 
genau und habe bei meinen ergebnisse eine genauigkeit von ca 97-98 % 
erreicht also bis auf die 3 stelle hinter dem komma richtig. Damit 
funktioniert es genau genug

Grüße

von Peter (Gast)


Lesenswert?

ihr müsst bei dem eben geschrieben kommentar

x durch -t/Tau ersetzten


Fehler von mir

von Matthias L. (Gast)


Lesenswert?

... mir auf die Schulter klopf ...

;-)

von resterampe (Gast)


Lesenswert?

Matthias Lipinsky schrieb:
> ... mir auf die Schulter klopf ...
>
> ;-)
siehe decius Punkt 1)
;-)

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.