W
etsmart schrieb:
Mathematisch hab ich da keine Probleme mit, aber ich hänge ja schon beim Programmieren, wenn es um die Messwerte finden geht. Gibt es denn kein schlaues Verfahren was mir nicht bekannt ist. Ich habe leider nichts genaues über das Thema LookUpTable gefunden. Aber das scheint mir das richtige zu sein. Zumindest muss man da auch den nächstliegenden Punkt aus einer Tabelle bestimmen können.
Um den nächstliegenden Punkt zu finden, musst Du alle Punkte abfragen und bewerten, zumal sie nach Deiner Aussage nicht sortiert sind. Eine andere Möglichkeit gibt es nicht.
etsmart schrieb:
Was nicht funktioniert, ist das bei der Suche oft ein falscher Messwert zurückgegeben wird.
Ein Zahlenbeispiel wäre hilfreich. Obwohl ich meine, dass es an Deiner Methode liegt, den 'Raum' zu bestimmen. Mal angenommen, Du hast zwei Punkte
1.) T=23C U=220V I=50mA=0.05A
2.) T=23C U=300V I=60mA=0.06A
weiter hast Du einen Wert sagen wir mal bei
T=23C U=221V I=0.05A
dieser liegt doch wohl 'näher' an 1.) als an 2.), aber Deine Raum-Berechnung ergibt:
1.) |220-221| = 1 T und I sind gleich, werden also nicht berücksichtigt und
2.) |300-221| * |0.06-0.05| = 0.79
also ist der Raum bei 2.) kleiner als bei 1.), was aber offensichtlich falsch ist.
Ich würde Dir vorschlagen, die Werte für T, U und I auf einen sinnvollen Bereich zu normieren, so dass die einzelnen Werte immer im Bereich von 0 bis 1 liegen und dann die Quadratsumme dieser normierten Werte zu bestimmen.
In C++ gibt es für eine solche Suche den Algorithmus min_element, der aber mit einem Iterator-Paar arbeitet. Du hast als Input aber drei (Paare) von Iteratoren bzw. Pointern. Wenn Du die Messwerte in eine Struktur (z.B. TUI) zusammenfasst, so könnte der Code so aussehen:
int /*CSVInterface::*/FindTransferCharacter( int size, TUI* aTUI, TUI dTUI )
{
return std::min_element( aTUI, aTUI + size, LessEON( dTUI ) ) - aTUI;
}
LessEON ist ein Funktor, der zwei Mess-(TUI-)Werte vergleicht; etwa so
class LessEON
{
public:
explicit LessEON( const TUI& tui )
: m_ref( tui )
{}
// -- liefert 'true' falls a näher an m_ref liegt, als b
bool operator()( const TUI& a, const TUI& b ) const
{
return abstand( a - m_ref ) < abstand( b - m_ref );
}
private:
TUI m_ref;
};
so und jetzt fehlt nur noch die TUI-Struktur, mit der man rechnen kann
struct TUI // Tripel Temperatur, Spannung, Strom
{
TUI( double t, double u, double i )
: m_T( t ), m_U( u ), m_I( i )
{}
TUI operator-( const TUI& b ) const
{
return TUI( m_T - b.m_T, m_U - b.m_U, m_I - b.m_I );
}
friend double abstand( const TUI& tui )
{
// das wäre der Raum-Algorithmus ..
if( tui.m_T == 0.0 && tui.m_U == 0.0 && tui.m_I == 0.0 )
return 0.0;
double erg = 1.0;
if( tui.m_T != 0.0 ) erg *= std::abs( tui.m_T );
if( tui.m_U != 0.0 ) erg *= std::abs( tui.m_U );
if( tui.m_I != 0.0 ) erg *= std::abs( tui.m_I );
return erg;
}
private:
double m_T, m_U, m_I;
};
alternativ dazu - normierte Werte in TUI vorausgesetzt
friend double abstand( const TUI& tui )
{
return tui.m_T * tui.m_T + tui.m_U * tui.m_U + tui.m_I * tui.m_I;
}
Gruß
Werner