Option Explicit
Function TrigenVB(dMin, dMl, dMax, dPP1, dPP2, dRandNo)
Dim dLower, dUpper As Double
Call TrigenSize(dMin, dMl, dMax, dPP1, dPP2, dLower, dUpper)
TrigenVB = TriangVB(dLower, dMl, dUpper, dRandNo)
End Function
Sub TrigenSize(dMin, dMl, dMax, dPP1, dPP2, dLower, dUpper)
Dim dA, dB, dC, dP1, dP2, dL, dU, dM, dQ, dR, dN, dSign As Double
Dim dBracket1, dSqrtBracket1, dBracket2, dF1n, dF2n, dF1nDash, dF2nDash As Double
Dim dNplusQ, dOneMinusP1, dCorr, dH, dH1, dH2 As Double
Dim iKtr As Integer
Const sOne As Single = 1#
dA = dMin
dB = dMax
dC = dMl
dP1 = dPP1 / 100#
dP2 = sOne - (dPP2 / 100)
dSign = sOne
dR = dB - dA
dQ = dC - dA
If ((dA > dC) Or (dC > dB)) Then
MsgBox ("Check Your Entry data it is inconsistent!")
GoTo endhere
End If
If (dP1 = 0) Then
dM = 0#
If (dP2 = 0) Then
dN = dR
GoTo closeenough
End If
dBracket1 = (2 * dR - dQ * dP2)
dN = (dBracket1 + Sqr(dBracket1 * dBracket1 - 4# * (sOne - dP2) * dR * dR)) / (2# * (sOne - dP2))
GoTo closeenough
End If
If (dP2 = 0) Then
dN = dR
dBracket1 = dP1 * (dQ + dR)
dM = (dBracket1 + Sqr((dBracket1 * dBracket1) + 4 * (sOne - dP1) * dQ * dP1 * dR)) / (2# * (sOne - dP1))
GoTo closeenough
End If
dN = dR * (sOne + 4 * dP2)
For iKtr = 1 To 50 Step 1
dNplusQ = dN + dQ
dOneMinusP1 = sOne - dP1
dBracket1 = dP1 * dP1 * dNplusQ * dNplusQ + 4 * dOneMinusP1 * dP1 * dN * dQ
If (dBracket1 < 0) Then
MsgBox ("Too Much Weight in the Tails")
dM = 0
dN = dR
GoTo closeenough
End If
dSqrtBracket1 = Sqr(dBracket1)
dF2n = ((dP1 * dNplusQ) + dSign * dSqrtBracket1) / (2# * dOneMinusP1)
dBracket2 = (2 * dR + dP2 * dF2n - dP2 * dQ)
dF1n = dN * dN * (sOne - dP2) - dN * dBracket2 + (dR * dR + dP2 * dQ * dF2n)
dF2nDash = (dP1 + (0.5 * dSign * (2 * dP1 * dP1 * (dN + dQ) + 4# * dOneMinusP1 * dP1 * dQ) / dSqrtBracket1)) / (2# * dOneMinusP1)
dF1nDash = (2 * dN * (sOne - dP2)) - (dN * dP2 * dF2nDash) - (dBracket2) + (dP2 * dQ * dF2nDash)
dCorr = dF1n / dF1nDash
dN = dN - dCorr
dM = dF2n
If (Abs(dCorr / dN) < 0.00000001) Then GoTo closeenough
Next iKtr
MsgBox ("No convergence")
closeenough:
dU = dN + dA
dL = -dM + dA
dH = 2 / (dU - dL)
dH1 = dH * (dA - dL) / (dC - dL)
dH2 = dH * (dU - dB) / (dU - dC)
If (dH1 < 0 Or dH2 < 0) Then
MsgBox ("Too Much Weight in the Tails")
dU = dB
dL = dA
End If
dLower = dL
dUpper = dU
endhere:
End Sub
Function TriangVB(dMin, dMl, dMax, dPval) As Double
Dim dA, dB, dC, dP, dBminA, dCminA, dBminC, dPminl As Double
dA = dMin
dB = dMax
dC = dMl
dP = dPval
If ((dB < dC) Or (dC < dA) Or (dP > 1#) Or (dP < 0#)) Then
MsgBox ("Error1 in i/p data")
TriangVB = 0#
GoTo endroutine
End If
dCminA = dC - dA
dBminA = dB - dA
dBminC = dB - dC
dPminl = dCminA / dBminA
If (dP = 0) Then
TriangVB = dA
ElseIf (dP = 1#) Then TriangVB = dB
ElseIf (dP < dPminl) Then TriangVB = dA + ((dP * dBminA * dCminA) ^ 0.5)
Else
TriangVB = dB - (((1# - dP) * dBminA * dBminC) ^ 0.5)
End If
endroutine:
End Function
|