moin
dieser elend langsame algorithmus hat mich jetzt doch ganz schön genervt ... also hab ich mir was neues überlegt. und siehe da: das ganze benötigt nur einen bruchteil der zeit. also stell ich das ganze hier mal vor, falls jemand anderes mal noch auf die idee kommen sollte, ein ähnliches problem lösen zu wollen:
Code:
Call ChnLinGen("[3]/SplineIndizes",1,chnlength("[3]/Zeitkanal"),chnlength("[3]/Zeitkanal"))
Call ChnMultipleSort("[3]/Temperaturen_Momentanwerte","[3]/SplineIndizes",0,0)
for counti=1 to chnlength("[3]/sortedX")
if IsNull( chdx(counti,CNo("[3]/sortedX")) ) then
chdx(counti,CNo("[3]/sortedX"))=10000
end if
next
Call ChnPropSet(CNo("[3]/sortedX"),"length",chnlength("[3]/Zeitkanal"))
Call ChnCharacter(CNo("[3]/sortedX"))
Call ChnMapLinCalc("[3]/Temperaturen_KL","[3]/Kennlinie 1","[3]/sortedX","SplineKL1",0,"const. Value",NoValue)
for counti=1 to chnlength("[3]/Zeitkanal")
index=chd(counti,"[3]/SortedY1")
chdx(index,CNo("[3]/Spline_Druck_Momentanwerte"))=chd(counti,"[3]/SplineKL1")
next
zur erklärung: zunächst erzeuge ich mir einen kanal, der einfach nur die zahlen von 1 bis x enthält ... mit der länge, die mein ergebniskanal einmal haben soll.
Code:
Call ChnLinGen("[3]/SplineIndizes",1,chnlength("[3]/Zeitkanal"),chnlength("[3]/Zeitkanal"))
anschließen sortiere ich meinen kanal mit den momentanwerten der temperatur der größe nach:
Code:
Call ChnMultipleSort("[3]/Temperaturen_Momentanwerte","[3]/SplineIndizes",0,0)
dabei wird dann auch gleich mein kanal mit den indizes mitsortiert, und zwar nach dem selben muster, wie der temperaturkanal. somit erhalt ich mir die information über die richtige reihenfolge der temperaturen. die dabei entstehenden ergebniskanäle tragen die namen sortedX (temperaturen) und sortedY1 (indizes). alle NoValues werden bei dieser sortierung automatisch ans ende des ergebniskanals geschoben.
anschließend ersetze ich alle NoValues in meinem sortierten kanal durch einen wert, der außerhalb des zu erwartenden wertebereichs liegt. dies geschieht, weil der anschließende befehl zu linearen abbildung scheinbar nicht mit kanälen klarkommt, die novalues enthalten. allerdings können werte, welche außerhalb des wertebereichs liegen und damit extrapoliert werden müssen, automatisch im ergebniskanal durch NoVaues ersetzt werden ... und somit bekomme ich am ende wieder an den richtigen stellen meine NoValues.
ich habe mich an dieser stelle für den wert 10000 entschieden, da ich hier mit wassertemperaturen arbeite und ein solcher wert in der realität wohl recht unwahrscheinlich ist ;-)
Code:
for counti=1 to chnlength("[3]/sortedX")
if IsNull( chdx(counti,CNo("[3]/sortedX")) ) then
chdx(counti,CNo("[3]/sortedX"))=10000
end if
next
Call ChnPropSet(CNo("[3]/sortedX"),"length",chnlength("[3]/Zeitkanal"))
Call ChnCharacter(CNo("[3]/sortedX"))
nun kommt die eigentliche interpolation: ich verwende hier eine lineare abbildung, weil mir das von der genauigkeit her einfachn reicht ... und schnell ist das ganze auch noch.
Code:
Call ChnMapLinCalc("[3]/Temperaturen_KL","[3]/Kennlinie 1","[3]/sortedX","SplineKL1",0,"const. Value",NoValue)
wie schon beschrieben werden hier alle zu extrapolierenden werte im ergebnis durch NoValues ersetzt.
abschließend muss der ergebniskanal nur noch in der richtigen reihenfolge wieder zusammengebaut werden. dazu benutze ich meinen am anfang mitsortierten indizeskanal:
Code:
for counti=1 to chnlength("[3]/Zeitkanal")
index=chd(counti,"[3]/SortedY1")
chdx(index,CNo("[3]/Spline_Druck_Momentanwerte"))=chd(counti,"[3]/SplineKL1")
next
es gibt sicher noch wesentlich elegantere algorithmen ... aber der hier beschriebene funktioniert (und das in einer annehmbaren zeit).
mfg daniel