/ / vba Excel inverse kubische Spline-Interpolation - Excel, VBA, Interpolation, Spline

vba Excel inverse kubische Spline-Interpolation - Excel, VBA, Interpolation, Spline

Ich bin kürzlich auf ein Problem mit einem Datensatz gestoßenHabe, da seine "Auflösung" viel zu klein ist. Der Datensatz ist charakterisiert, um ein Maximum (0) aufzuweisen, das nicht wirklich sein Maximum ist, da alle Zahlen auf die höhere Zahl normiert sind, die innerhalb ihrer "Auflösung" gefunden wird, die im Grunde die "1 zu 1 Einheit" des "X" ist. Säule. Die Y-Werte sind immer einer parabolischen Kurve ähnlich.

   Y       X
-34,32   -93
-16,56   -92
-10,04   -91
-6,03    -90
-3,34    -89
-1,56    -88
-0,47    -87
0       -86
-0,10    -85
-0,78    -84
-2,11    -83
-4,20    -82
-7,36    -81
-12,31   -80
-22,03   -79
-25,17   -78

Jetzt weiß ich sicher, dass die 0 irgendwo zwischen 0 und -0,10 oder zwischen 0 und -0,47 liegen sollte. Eine lineare Interpolation würde mir zu viele Fehler geben, also würde ich einen Cubic Spline verwenden.

Was ich tun muss, ist den X-Parameter zu berechnen, wo mein Y WIRKLICH = 0 ist.

Schade, dass ich das, was ich im Internet gefunden habe, nicht verwenden konnte, weil jede Funktion, die ich probiere, Y aus einem bestimmten X berechnet (unter einem Beispiel von Code). Kann mir jemand helfen?

Function SpLine(PeriodCol As Range, RateCol As Range, x As Range)

Dim Period_Count As Integer
Dim Rate_Count As Integer
Dim c As Integer
Dim n As Integer
Dim i, k As Integer
Dim p, qn, sig, un As Single
Dim klo, khi As Integer
Dim h, b, a As Single

" shows the calculation of a cubic spline interpolated value given known values for fixed periods

Period_Count = PeriodCol.Rows.Count
Rate_Count = RateCol.Rows.Count

If Period_Count <> Rate_Count Then
SpLine = "Error: Range count dos not match"
GoTo endnow
End If

ReDim xin(Period_Count) As Single
ReDim yin(Period_Count) As Single

For c = 1 To Period_Count
xin(c) = PeriodCol(c)
yin(c) = RateCol(c)
Next c

ReDim u(Period_Count - 1) As Single
ReDim yt(Period_Count) As Single
n = Period_Count
yt(1) = 0
u(1) = 0

For i = 2 To n - 1
sig = (xin(i) - xin(i - 1)) / (xin(i + 1) - xin(i - 1))
p = sig * yt(i - 1) + 2
yt(i) = (sig - 1) / p
u(i) = (yin(i + 1) - yin(i)) / (xin(i + 1) - xin(i)) - (yin(i) - yin(i - 1)) / (xin(i) - xin(i - 1))
u(i) = (6 * u(i) / (xin(i + 1) - xin(i - 1)) - sig * u(i - 1)) / p
Next i

qn = 0
un = 0
yt(n) = (un - qn * u(n - 1)) / (qn * yt(n - 1) + 1)

For k = n - 1 To 1 Step -1
yt(k) = yt(k) * yt(k + 1) + u(k)
Next k

klo = 1
khi = n

Do
k = khi - klo
If xin(k) > x Then
khi = k
Else
klo = k
End If

k = khi - klo
Loop While k > 1

h = xin(khi) - xin(klo)
a = (xin(khi) - x) / h
b = (x - xin(klo)) / h
SpLine = a * yin(klo) + b * yin(khi) + ((a ^ 3 - a) * yt(klo) + (b ^ 3 - b) * yt(khi)) * (h ^ 2) / 6

endnow:

End Function

Antworten:

0 für die Antwort № 1

Nun, da niemand antwortete, nahm ich an, dass ich einen anderen Weg finden musste.

Da meine Werte dem y einer parabolischen Kurve ähneln, habe ich den Koeffizienten eines Polynoms dritten Grades gefunden, der dieser Kurve angenähert ist.

Dies wird durch Füllen einer Formel in einem Array von Zellen 1x4 gemacht:

worksheet.MyRange1x4.formulaarray = "=LINEST(" & MyX & "," & MyY & "^{1,2,3})"

Wo MyX und MyY sind wieder Arrays mit der gleichen Dimension (1 x n)

Die Ergebnisse sind die "a", "b", "c" und "d" aus dem Polynom ax^3+bx^2+cx+d

Nun, wenn ich das X von meinem Maximum finden wollte, musste ich nur ein Delta lösen, das dem der Gleichungen zweiten Grades sehr ähnlich ist: Delta = (-b (+/-) SQRT(b^2 - 3ac))/3a

Erzwingt das Delta 0 zu sein, habe ich 2 mögliche erhaltenX-Werte (wegen der +/- SQRT), von denen einer definitiv in dem Bereich war, wo alle meine fast maximalen Werte waren, und der andere war völlig falsch mit diesem Bereich.

Durch die Auswahl des richtigen habe ich endlich mein X gefunden.