Korrekturfunktion in Programm einbinden

Gast #513721
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?
Moderator Persönliche Seite #513726
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.
Gast #513739
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
}
Gast #513742
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
Gast #513749
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.
Gast #513757
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
Gast #513765
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.
Gast #513768
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
Gast #513801
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
Gast #513838
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.
Gast #513935
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

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