e_funktion ohne Floating unit rechnen

Gast #2334823
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
Gast #2334939
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.
Gast #2334955
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.
Gast #2334962
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.
Gast #2334972
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.
Gast #2335002
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.
Gast #2335015
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
Gast #2335021
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.
Persönliche Seite #2335165
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 :-)
Gast #2336661
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...
Gast #2339262
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren