在阵列点之间插值

时间:2014-07-17 10:03:17

标签: arrays vba excel-vba interpolation excel

在下面的代码中我构建了2个数组:

  • 一个包含“度数据”(所以基本上是逐个增加的整数数组),表示圆周度数的一部分。

  • 第二个是“功率数据”(一个Double,其值保持或多或少立方增加,直到最大值对应于第一个数组中的0。然后它们将随着它们的增加而减少)。该数组例如来自大于-4.0到大于或小于-4.0的值。

我认为我可以将第二个“简化”为抛物线(看起来非常像一个)并使用其系数(通过LinEst计算)A,B,C和D来插入之间的数据分。

我需要的是以0.1度的精度找到最接近-3.0的2个数字,然后找到它们的“距离”(以度为单位)。 问题是:我无法做到。我缺少一些东西,系数似乎不代表我的数据集。

Dim i As Integer, j As Integer
Dim MaxVal As Double, MaxAngle As Integer, CyclicAngle As Double
Dim XValues() As Double, YValues() As Double, Coeff As Variant
Dim LeftAngle As Double, RightAngle As Double, LeftAngleValue As Double, RightAngleValue As Double

' Searches for the maximum value and its angle
MaxVal = -80
ReDim YValues(359 * 3 + 2)
For i = 3 To 362 ' This will fill arrays from a worksheet (defined as Public in
' another subroutine) in which the data starts from row 3. I need the data stored in
' the 2nd column)
    For j = 0 To 2 ' since the array represents a circumference, i make it "cyclic"
        YValues((i - 3) + (360 * j)) = TargetSheet.Cells(i, 2)
    Next j
    If TargetSheet.Cells(i, 2) > MaxVal Then
        MaxVal = TargetSheet.Cells(i, 2)
        MaxAngle = i - 3
    End If
Next

' The following searches the "middle" maximum
i = 0
j = 0
Do Until j = 2
    If YValues(i) = MaxVal Then
        j = j + 1
        CyclicAngle = i
    End If
    i = i + 1
Loop
' Searches in the middle for the <-3 (we name it "-4") values
i = CyclicAngle
Do Until YValues(i) < -3
    i = i + 1
Loop
RightAngle = i + 1
i = CyclicAngle
Do Until YValues(i) < -3
    i = i - 1
Loop
LeftAngle = i - 1

' Copying only the "-4" to "-4"
ReDim XValues(RightAngle - LeftAngle)
For i = 0 To RightAngle - LeftAngle
    XValues(i) = YValues(LeftAngle + i)
Next i
' Now correctly store the data in a new ordered array
ReDim YValues(UBound(XValues))
For i = 0 To UBound(XValues)
    YValues(i) = XValues(i)
    XValues(i) = LeftAngle - 360 + i
Next i

这是批评点:

' Gets the coefficients of a 3rd degree curve representing the Y-Array
Coeff = Application.LinEst(Application.Transpose(YValues), Application.Power(Application.Transpose(XValues), Array(1, 2, 3)), True, False)

' Sets the arrays to have a point every 0.1°
LeftAngle = LeftAngle * 10
RightAngle = RightAngle * 10
MaxAngle = MaxAngle * 10
ReDim XValues(RightAngle - LeftAngle)
ReDim YValues(RightAngle - LeftAngle)
For i = LeftAngle To RightAngle
    XValues(i - LeftAngle) = i / 10
    YValues(i - LeftAngle) = Coeff(1) * (i / 10) ^ 3 + Coeff(2) * (i / 10) ^ 2 + Coeff(3) * (i / 10) + Coeff(4)
Next

现在,如果我查看YValues数组,那么存储在里面的数字看起来并不是绝对的。 那么如何进行插值以找到那些-3?

1 个答案:

答案 0 :(得分:0)

错误出现在这段代码中:我不认为我无法“旋转”XValues数组

' Now correctly store the data in a new ordered array
ReDim YValues(UBound(XValues))
For i = 0 To UBound(XValues)
    YValues(i) = XValues(i)
    XValues(i) = LeftAngle + i ' Was LeftAngle - 360 + i
Next i

我现在应该能够通过简单的循环迭代找到我的-3.0。 当然有一些障碍,但由于我有LeftAngle和RightAngle参考,我应该能够解决所有问题。

完整解决方案

请查看我的问题并使用上面的代码进行更正。从“批评点”来看:

'获取表示Y阵列的3度曲线的系数     '并建立一个插值数组,其点数每0.1°     Coeff = Application.LinEst(Application.Transpose(YValues),Application.Power(Application.Transpose(XValues),Array(1,2,3)),True,False)     'TargetSheet.Range(“E1:H1”)= Coeff

' Sets the arrays to be every 0.1°
LeftAngle = LeftAngle * 10
RightAngle = RightAngle * 10
j = CInt(LeftAngle)
k = CInt(RightAngle)
ReDim XValues(k - j)
ReDim YValues(k - j)
For i = j To k
    XValues(i - LeftAngle) = i / 10
    YValues(i - LeftAngle) = Coeff(1) * (i / 10) ^ 3 + Coeff(2) * (i / 10) ^ 2 + Coeff(3) * (i / 10) + Coeff(4)
Next
' Now searches for the -3dB angles with a better resolution
RightAngleValue = 10
LeftAngleValue = 10
CyclicAngle = CyclicAngle * 10
i = 0
Do Until XValues(i) > CyclicAngle / 10
    If Abs(YValues(i) +3) < LeftAngleValue Then
        LeftAngleValue = Abs(YValues(i) + 3)
        LeftAngle = i * 0.1
    End If
    i = i + 1
Loop
Do Until i > UBound(XValues)
    If Abs(YValues(i) +3) < RightAngleValue Then
        RightAngleValue = Abs(YValues(i) + 3)
        RightAngle = i * 0.1
    End If
    i = i + 1
Loop
myFunction = RightAngle - LeftAngle