Forum: Compiler & IDEs Korrekturfunktion in Programm einbinden


von Mister mit Kanister (Gast)


Lesenswert?

Hallo,

ich möchte eine Korrekturfunktion erstellen, womit ich bestimmte 
Variablenwerte korrigieren kann, also Anhand von:

a = Korrekturfunktion(variable b);

Das Problem ist, dass ich die "Korrekturfunktion" nicht habe, sondern 
nur eine Tabelle mit bestimmten diskreten Werten. Das könnte ich mit IF 
oder SWITCH Abfragen machen, wäre aber sehr aufwendig und ich kann nur 
die Werte zuweisen, die in der Tabelle stehen, nicht Werte die zwischen 
den Tabellenwerten liegen.


Jetzt die Frage, gibt es eine Möglichkeit aus den Tabellenwerten eine 
Funktion zu erstellen? Stellt gcc gewisse Funktionen bereit, die einem 
die Korrekturfunktionen erleichtern? Vielleicht über arrays oder 
ähnliches?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Mit dem GCC selbst hat das nichts zu tun.  Die Frage ist ja auch,
wie du die Approximation durchführen willst: lineare Interpolation
zwischen den Stützstellen, Polynom n-ten Grades, das durch alle
n+1 Stützstellen durchgeht, Polynom m-ten Grades mit m < n+1 und
geringstem quadratischen Fehler zu allen Stützstellen?

Für all diese Dinge hat die Mathematik Lösungen parat.  Die musst
du in irgendein Programm gießen (das kann ein GCC sein, dass kann
eine Scriptsprache sein wie Perl oder Python, das kann ein
Mathematikprogramm sein), und das lässt du dann deine Tabelle
berechnen.

von Roland Praml (Gast)


Lesenswert?

Am Einfachsten (und meistens auch ausreichend) ist wohl lineare 
Interpolation

Mach dir ne Tabelle, welche soritert ist, dann läust die Tabelle durch, 
schaust wann du zum ersten mal größer oder gleich dem Wert im Array 
bist.
(bei größeren Tabellen kann man auch binäre Suche verwenden)
Wenn du die Stelle gefunden hast, dann bist zwischen 2 Stützsstellen.
Dann musst noch das Verhältnis ausrechen zwischen den 2 Stützsstellen 
und auf die andere Spalte anwenden. Hab hier mal ein Beispiel wie ich 
die Werte von einen Temp-Fühler vom ADC auf °C umrechne
1
int __attribute__ ((progmem)) adc_table [20*2] = {
2
  -999,  0,
3
  -350,  64,
4
  -200,  129,
5
  -100,  171,
6
  00,  213,
7
  150,  273,
8
  250,  312,
9
  350,  351,
10
  450,  389,
11
  600,  444,
12
  750,  497,
13
  900,  549,
14
  1050,  600,
15
  1200,  649,
16
  1500,  743,
17
  1800,  833,
18
  2100,  917,
19
  2300,  972,
20
  2490,  1021,
21
  3000,  1023 };
22
23
int adc_getTemp(int adc) {
24
  unsigned char i;
25
  int x1,x2,t1,t2; 
26
  for (i = 1; i < 19; i++) {
27
    if (PRG_RDInt(&adc_table[i*2+1]) >= adc) break;
28
  }
29
  x1 = PRG_RDInt(&adc_table[i*2-1]);
30
  x2 = PRG_RDInt(&adc_table[i*2+1]);
31
  t1 = PRG_RDInt(&adc_table[i*2-2]);
32
  t2 = PRG_RDInt(&adc_table[i*2]);
33
  
34
35
  return ((adc-x1) * (t2-t1)) / (x2-x1) + t1;
36
}

von Falk (Gast)


Lesenswert?

>Jetzt die Frage, gibt es eine Möglichkeit aus den Tabellenwerten eine
>Funktion zu erstellen? Stellt gcc gewisse Funktionen bereit, die einem
>die Korrekturfunktionen erleichtern? Vielleicht über arrays oder
>ähnliches?

GCC ist nur ein C-Compiler. Du brauchst ein Programm zur 
Datenverarbeitung/analyse. Versuchs mal mit Excel, das kann AFAIK 
lineare Regression sowie quadratische Interpolation.

MfG
Falk

von Roland Praml (Gast)


Lesenswert?

ich seh grad dass der code noch für ne alte gcc-Version ist.
Besser man verwendet anstatt PRG_RDint pgm_... aber das wirst schon 
selber heraus finden ;-)

von Mister mit Kanister (Gast)


Lesenswert?

Das steuert genau in die Richtung wo ich hin möchte. Es wäre schon eine 
Hilfe, wenn man aus den einfachen Tabellenwerten mit Hilfe eines 
Programms irgendwie eine Mathemantische Funktion erstellen könnte. Die 
dazwischenliegenden Werte würde ausreichen linear zu interpolieren oder 
sonstwie anzunähern. Leider habe ich nichts passendes gefunden.

Ich werde mal versuchen über eine Switch Anweisung das abzudecken, die 
dazwischenliegenden Werte einfach zu berechnen.

von pumpkin (Gast)


Lesenswert?

interpolationsformel von Lagrange oder Newton. gibt natürlich noch 
andere verfahren um eine funktion aus stützstellen zu erhalten. ein 
matheprogramm ist da definitiv zu empfehlen, ansonsten kann es passieren 
dass du ewig rechnest.

pumpkin

von Mister mit Kanister (Gast)


Lesenswert?

Danke Leute!

ich versuche mal den Lösungsansatz von Roland umzusetzen. Danach melde 
ich mich wieder zu Wort.

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

OpenOfficeCalc legt immerhin eine Gerade durch die Tabellenwerte, als 
erster Anhaltspunkt welche Kurvenform geeignet wäre. Durch 
Logarithmieren der Tabellenwerte kann man auch Geraden in 
"halblogaritmischen" Diagrammen zeichnen lassen.
"lineare Regression sowie quadratische Interpolation" hab ich in der 
OpenOffice-Hilfefunktion nicht gefunden, aber vielleicht nur die 
falschen Suchbegriffe benutzt.

von pumpkin (Gast)


Lesenswert?

edit:

aber um deine zwischenwerte linear zu interpolieren reicht eine kleine 
funktion. etwa so: nehme den nächst kleineren und den nächst größeren. 
größerer - kleinerer = deltaY. dein deltaX (also x beim größeren - x 
beim kleineren) ist vermutlich immer gleich. somit kannst du die 
steigung zwischen den beiden punkten ausrechnen (deltaY/deltaX = dY/dX). 
dann nimmst du dein aktuellen X wert und ziehst das X des kleineren ab 
und multiplizierst das ergebniss mit dem dY/dX. kleineren Y-wert 
hinzuaddiert, fertig.

pseudocode also:

( (( Y[größer] - Y[kleiner] )/( X[größer] - X[kleiner] )) * ( X[aktuell] 
- X[kleiner] ) ) + Y[kleiner]

pumpkin

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

Gnuplot wird oft empfohlen:
http://gnuplot.sourceforge.net/demo/
"Math functions and curve fitting"

von Mister mit Kanister (Gast)


Lesenswert?

Ich glaube mich zu erinnern, dass es da auch was passendes in Matlab 
gab. Hab das Prog aber leider nicht zur Hand.

von pumpkin (Gast)


Lesenswert?

>> Das steuert genau in die Richtung wo ich hin möchte. Es wäre schon eine
>> Hilfe, wenn man aus den einfachen Tabellenwerten mit Hilfe eines
>> Programms irgendwie eine Mathemantische Funktion erstellen könnte. Die
>> dazwischenliegenden Werte würde ausreichen linear zu interpolieren oder
>> sonstwie anzunähern. Leider habe ich nichts passendes gefunden.

was willst du eigentlich? eine mathematische funktion? lineare 
interpolation zwischen den werten? wenn du eine stetige funktion willst, 
bekommst du ein polynom x-ten grades, wobei x+1 die anzahl deiner 
stützstellen ist (wie Jörg schon schrieb). das auf einem µC ist zwar 
machbar aber nicht empfehlenswert. soll es denn überhaupt für einen µC 
sein?

pumpkin

von Mister mit Kanister (Gast)


Lesenswert?

Eine Funktion wäre am genauesten. Aber ich habe ca. 45 Stützstellen, 
diese in ein Polynom zu gießen wäre glaube ich zu aufwendig. Habe von 
der MAthe nicht so die Ahnung, aber müsste man dann nicht vorher ein 
Gleichungssystem mit 44 unbekannten lösen?

Ich habe jetzt eine einfache Funktion gemacht, die auf nem Atmega laufen 
soll. Tabellenwerte vergleichen und dann lineare Interpolation anwenden 
und so den zugehörigen Wert approximieren. Die Genauigkeit ist da 
ausreichend für meine Zwecke.

Eine exakte Funktion mit 44 Polynomen wäre Seitens der Implementation zu 
aufwendig und (für mich) zu schwierig.

von Chef (Gast)


Lesenswert?

Hallo, Du solltest die Interpolation bereits explizit vorziehen und 
nicht die Stützstellen, sondern die Steigung und den Achsabschnitt 
vorgeben. Dann gibt es weniger zu rechnen.

von Falk (Gast)


Lesenswert?

@Mister mit Kanister

>Eine Funktion wäre am genauesten. Aber ich habe ca. 45 Stützstellen,
>diese in ein Polynom zu gießen wäre glaube ich zu aufwendig. Habe von

Wieso, das macht das Programm für dich.

>der MAthe nicht so die Ahnung, aber müsste man dann nicht vorher ein
>Gleichungssystem mit 44 unbekannten lösen?

Nur wenn du ein Polynom 44. Grades haben willst. Aber meist tuts eins 
dritten Grades. Aber auch das rechnet dir das richtige Programm 
automatisch aus.

>Ich habe jetzt eine einfache Funktion gemacht, die auf nem Atmega laufen
>soll. Tabellenwerte vergleichen und dann lineare Interpolation anwenden
>und so den zugehörigen Wert approximieren. Die Genauigkeit ist da
>ausreichend für meine Zwecke.

Problem gelöst.

>Eine exakte Funktion mit 44 Polynomen wäre Seitens der Implementation zu
>aufwendig und (für mich) zu schwierig.

Braucht keiner, siehe oben.

MFG
Falk

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.