'This procedure calculates (in fact estimates) the Mean Value and the Standard Deviation of an
'arbitrary function f(x,y) of two independent normally distributed random variables x and y.
'The program uses the Monte Carlo Simulation Method. The function f(x,y) is specified in
'run-time and its values are calculated using the MS ScriptControl (msscript.ocx).
'Add Component: Microsoft script control 1.0 (msscript.ocx)
'Example:
'--------
'Given that random variable x follows the normal distribution (5,1) - with Mean value = 5 and
'Standard Deviation = 1 and that random variable y follows the normal distribution (4,2) - with
'Mean value = 4 and Standard Deviation = 2, What is the Mean value and the Standard Deviation
'of the function f(x,y) = x + x*y - y ?
'The Standard Deviation is the most difficult part to calculate here,
'yet note that not always even Mean_f = f(Mean_x, Mean_y) !
'Written by Vagelis Plevris, Greece
Private Sub cmdCALCULATE_Click()
Dim X_Values(), Y_Values(), F_Values() 'Allocatable arrays that will hold the values of x, y and f(x,y)
Const Pi = 3.14159265358979 'Pi value
Mean_X = Val(txtMeanX.Text) 'Mean value of Random Variable x (Given)
StDev_X = Val(txtStDevX.Text) 'Standard deviation of Random Variable x (Given)
Mean_Y = Val(txtMeanY.Text) 'Mean value of Random Variable y (Given)
StDev_Y = Val(txtStDevY.Text) 'Standard deviation of Random Variable y (Given)
N_MCS = Val(txtN.Text) 'Number of Monte Carlo Simulations to be done
'Redim arrays to hold the N_MCS data
ReDim X_Values(1 To N_MCS)
ReDim Y_Values(1 To N_MCS)
ReDim F_Values(1 To N_MCS)
'Randomize in order to obtain different results every time the program is run
Randomize
For j = 1 To Int(N_MCS / 2)
'Int(N_MCS / 2) because the random numbers are calculated in pairs, so we obtain 2 numbers each time (for every loop)
'Two Random numbers uniformly distributed in the [0,1) space
'(will be used later to generate the values of x)
u1x = Rnd
u2x = Rnd
'Another two Random numbers uniformly distributed in the [0,1) space
'(will be used later to generate the values of y)
u1y = Rnd
u2y = Rnd
'A pair of random numbers that follow the normal distribution (0,1):
'(0,1) means: Mean value = 0, Standard Deviation = 1
'(will be used later to generate the values of x)
Z1x = Sqr(-2 * Log(u1x)) * Sin(2 * Pi * u2x)
Z2x = Sqr(-2 * Log(u1x)) * Cos(2 * Pi * u2x)
'Another pair of random numbers that follow the normal distribution (0,1):
'(0,1) means: Mean value = 0, Standard Deviation = 1
'(will be used later to generate the values of y)
Z1y = Sqr(-2 * Log(u1y)) * Sin(2 * Pi * u2y)
Z2y = Sqr(-2 * Log(u1y)) * Cos(2 * Pi * u2y)
'A pair of random numbers that follow the given normal distribution for x (Mean_X, StDev_X):
'(Mean_X, StDev_X) means: Mean value = Mean_X, Standard Deviation = StDev_X
'(will be used as values for x)
X1 = Mean_X + Z1x * StDev_X
X2 = Mean_X + Z2x * StDev_X
'Assign these values to the corresponding array X_Values
X_Values(2 * j - 1) = X1
X_Values(2 * j) = X2
'A pair of random numbers that follow the given normal distribution for y (Mean_Y, StDev_Y):
'(Mean_Y, StDev_Y) means: Mean value = Mean_Y, Standard Deviation = StDev_Y
'(will be used as values for y)
Y1 = Mean_Y + Z1y * StDev_Y
Y2 = Mean_Y + Z2y * StDev_Y
'Assign these values to the corresponding array Y_Values
Y_Values(2 * j - 1) = Y1
Y_Values(2 * j) = Y2
'Now calculate the values of the function f(x,y) and assign these values to the corresponding array F_Values
F_Values(2 * j - 1) = Func_f_xy(X1, Y1)
F_Values(2 * j) = Func_f_xy(X2, Y2)
Next j
'The arrays are ready, so we can now calculate the Mean value of f(x,y) and its Standard Deviation
'For verification purposes, we will also calculate the Mean value and the Standard Deviation of both x and y variables
'The obtained values for the Mean and Standard Deviation of x and y variables
'should be close to the initially given values Mean_X, StDev_X, Mean_Y, StDev_Y
'Calculate the sum of the values of every array
sum_x = 0: sum_y = 0: sum_f = 0 'Set sum to zero
For n = 1 To N_MCS
sum_x = sum_x + X_Values(n)
sum_y = sum_y + Y_Values(n)
sum_f = sum_f + F_Values(n)
Next n
'Calculate the mean value (average) of every array
ave_x = sum_x / N_MCS 'Should be close to the given Mean value Mean_X, but not exactly equal to it
ave_y = sum_y / N_MCS 'Should be close to the given Mean value Mean_Y, but not exactly equal to it
ave_f = sum_f / N_MCS
'Calculate the Variance and the Standard Deviation of every array
adevx = 0: Varx = 0: epx = 0 'Set values to zero
adevy = 0: Vary = 0: epy = 0 'Set values to zero
adevf = 0: Varf = 0: epf = 0 'Set values to zero
For j = 1 To N_MCS
Sx = X_Values(j) - ave_x: epx = epx + Sx: adevx = adevx + Abs(Sx): px = Sx * Sx: Varx = Varx + px
Sy = Y_Values(j) - ave_y: epy = epy + Sy: adevy = adevy + Abs(Sy): py = Sy * Sy: Vary = Vary + py
Sf = F_Values(j) - ave_f: epf = epf + Sf: adevf = adevf + Abs(Sf): pf = Sf * Sf: Varf = Varf + pf
Next j
Varx = (Varx - epx ^ 2 / N_MCS) / (N_MCS - 1): Sdevx = Sqr(Varx)
'Sdevx should be close to the given Standard Deviation StDev_X, but not exactly equal to it
Vary = (Vary - epy ^ 2 / N_MCS) / (N_MCS - 1): Sdevy = Sqr(Vary)
'Sdevy should be close to the given Standard Deviation StDev_Y, but not exactly equal to it
Varf = (Varf - epf ^ 2 / N_MCS) / (N_MCS - 1): sdevf = Sqr(Varf)
'Write the result to the textbox
txtRESULT.Text = ""
txtRESULT.Text = txtRESULT.Text + "Mean of x = " + CStr(ave_x) + vbCrLf + "StDev of x = " + CStr(Sdevx) + vbCrLf + vbCrLf
txtRESULT.Text = txtRESULT.Text + "Mean of y = " + CStr(ave_y) + vbCrLf + "StDev of y = " + CStr(Sdevy) + vbCrLf + vbCrLf
txtRESULT.Text = txtRESULT.Text + "Mean of f(x,y) = " + CStr(ave_f) + vbCrLf + "StDev of f(x,y) = " + CStr(sdevf) + vbCrLf
End Sub