【发布时间】:2014-07-17 10:03:16
【问题描述】:
在以下代码中,我构建了 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 呢?
【问题讨论】:
-
您在中间变量中继续查找“预期值”到哪一行?因为在不熟悉具体问题的情况下浏览整个代码看起来有点费时
-
好吧,我没有找到预期值,因为大部分代码都是为了让我们了解数组是如何填充的。最后,我找到了 3 级 LinEst 系数,但从那里开始......成为龙
-
你的 Leftangle,rightangle 变量是双精度的。使用双精度和索引运行循环不是一个好主意,使用双精度来提供数组大小当然不是一个好主意。将完成隐式转换,但我更愿意在顶部使用
Option Explicit并使用正确的数据类型。注册。具体问题,一旦类型设置正确(最好创建一个新变量为Long循环并初始化,保持角度为双) -
这可能不会有帮助:它们是 Double 因为我认为我可以使用它们来存储 exact 角度(对应于 -3 和 0.1 的值°分辨率)。提供了数组大小(如果您正在谈论
ReDims),因为我只想选择圆周的一部分。对于 LeftAngle/RightAngle 骑行,你是完全正确的...... -
是的,因此您将它们保持为双精度并使用长迭代器
标签: arrays vba excel interpolation