VBA为什么根据值是否在数组中来计算不同?

时间:2019-01-13 19:21:16

标签: excel vba range double mismatch

在Excel VBA中,我编写了代码来基于某些参数模拟某些价格,但是当其中一个参数来自数组而不是变量时,其中一个参数给出了完全不同的模拟结果,我无法理解(值使用数组时,“铜”的倍数在多次运行中变为负数)。

使用数组的版本:

'Calculate Price Matrix
For j = 1 To Years
    'For each Commodity
    For i = 1 To N
        'Generate Correlated Brownian Motions
        For k = 1 To i
            dW(i) = dW(i) + A(i, k) * 0.5
        Next k

        'Calculate Price for year
        S(i) = Exp(-Lambda(i)) * S(i) + (1 - Exp(-Lambda(i))) * Mu(i) + Sigma(i) * Sqr((1 - Exp(-2 * Lambda(i))) / (2 * Lambda(i))) * dW(i)

        'Populate Price in Model
        Sheets("Prices").Cells(i + 1, j + 2).Value = S(i)
    Next i
Next j

使用double的版本:

'Calculate Price Matrix
For j = 1 To Years            
    'For each Commodity
    For i = 1 To N
        'Generate Correlated Brownian Motions
        dW = 0.5

        'Calculate Price for year
        S(i) = Exp(-Lambda(i)) * S(i) + (1 - Exp(-Lambda(i))) * Mu(i) + Sigma(i) * Sqr((1 - Exp(-2 * Lambda(i))) / (2 * Lambda(i))) * dW

        'Populate Price in Model
        Sheets("Prices").Cells(i + 1, j + 2).Value = S(i)
    Next i
Next j

运行A(1,1)=1的两个代码应为S(1)...给出相同的结果,但完全没有。我什至尝试将dW(i) = dW(i) + A(i, k) * 0.5更改为dW(i) = 0.5。但是结果仍然不同。是什么导致此问题?

希望以前有人遇到过同样的问题。是MS Excel中的某种限制吗?

1 个答案:

答案 0 :(得分:0)

很抱歉缺少信息。以下是使用dW()范围的完整代码

Option Explicit
Sub SimulatePrices()
'Variables
    Dim Lambda() As Double
    Dim Sigma() As Double
    Dim Mu() As Double
    Dim Exp1() As Double
    Dim Exp2() As Double
    'Dim dW() As Double
    Dim A() As Double
    Dim S() As Double
    Dim i, j, k, N, Years As Long
'Define Ranges for Price Simulations
    Sheets("DataInput").Select
    N = Range(Cells(1, 1), Cells(1, 1).End(xlDown)).Rows.Count - 1
    Sheets("Prices").Select
    Years = Range(Cells(1, 2), Cells(1, 2).End(xlToRight)).Columns.Count - 1

    ReDim Lambda(1 To N)
    ReDim Sigma(1 To N)
    ReDim Mu(1 To N)
    ReDim S(1 To N)

    ReDim dW(1 To N)
    ReDim A(1 To N, 1 To N)

'Populate Variable Matrices
    Sheets("DataInput").Select

    For i = 1 To N

        'Populate OUP Parmameters
        S(i) = Cells(i + 1, 5)
        Lambda(i) = Cells(i + 1, 2)
        Sigma(i) = Cells(i + 1, 4)
        Mu(i) = Cells(i + 1, 3)

        'Populate Cholesky Matrix
        For j = 1 To N
            A(i, j) = Cells(i + 13, j + 1).Value
        Next j

    Next i

'Calculate Price Matrix
    For j = 1 To Years

        'For each Commodity
        For i = 1 To N

            'Generate Correlated Brownian Motions
             For k = 1 To i
                dW(i) = dW(i) + A(i, k) * MSRndNorm

             Next k

            'Calculate Price for year
                S(i) = Exp(-Lambda(i)) * S(i) + (1 - Exp(-Lambda(i))) * Mu(i) + Sigma(i) * Sqr((1 - Exp(-2 * Lambda(i))) / (2 * Lambda(i))) * dW(i)
            'Populate Price in Model
                Sheets("Prices").Cells(i + 1, j + 2).Value = S(i)
        Next i
Next j
Sheets("Prices").Activate
    Application.Calculation = xlAutomatic
End Sub

Function MSRndNorm() As Double
'Marsaglia-Bray modification of Box-Muller method
Dim U1, U2 As Double
Dim x As Double, y As Double
x = 1.1
While x > 1
U1 = Rnd()
U2 = Rnd()
U1 = 2 * U1 - 1
U2 = 2 * U2 - 1
x = U1 ^ 2 + U2 ^ 2
Wend
y = Sqr(-2 * Log(x) / x)
MSRndNorm = U1 * y
End Function