Code originally came from here : http://weblogs.asp.net/esanchez/arch...tion-in-c.aspx, has been converted from c# to vb.
Replicates the Norminv function found in excel.
P needs to be a random number between 0 and 1.
Hopefully this comes in handy for someone.
Code:'NORMINV DSITRIBUTION Public Function NormInv(ByVal p As Double, ByVal mu As Double, ByVal sigma As Double) As Double If p < 0 OrElse p > 1 Then Throw New ArgumentOutOfRangeException("The probality p must be bigger than 0 and smaller than 1") End If If sigma < 0 Then Throw New ArgumentOutOfRangeException("The standard deviation sigma must be positive") End If If p = 0 Then Return [Double].NegativeInfinity End If If p = 1 Then Return [Double].PositiveInfinity End If If sigma = 0 Then Return mu End If Dim q As Double, r As Double, val As Double q = p - 0.5 '-- use AS 241 --- ' double ppnd16_(double *p, long *ifault) ' ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3 ' ' Produces the normal deviate Z corresponding to a given lower ' tail area of P; Z is accurate to about 1 part in 10**16. ' If Math.Abs(q) <= 0.425 Then ' 0.075 <= p <= 0.925 r = 0.180625 - q * q val = q * (((((((r * 2509.08092873012 + 33430.5755835881) * r + 67265.7709270087) * r + 45921.9539315499) * r + 13731.6937655095) * r + 1971.59095030655) * r + 133.141667891784) * r + 3.38713287279637) / (((((((r * 5226.49527885285 + 28729.0857357219) * r + 39307.8958000927) * r + 21213.7943015866) * r + 5394.19602142475) * r + 687.187007492058) * r + 42.3133307016009) * r + 1) Else ' closer than 0.075 from {0,1} boundary ' r = min(p, 1-p) < 0.075 If q > 0 Then r = 1 - p Else r = p End If r = Math.Sqrt(-Math.Log(r)) ' r = sqrt(-log(r)) <==> min(p, 1-p) = exp( - r^2 ) If r <= 5 Then ' <==> min(p,1-p) >= exp(-25) ~= 1.3888e-11 r += -1.6 val = (((((((r * 0.000774545014278341 + 0.0227238449892692) * r + 0.241780725177451) * r + 1.27045825245237) * r + 3.6478483247632) * r + 5.76949722146069) * r + 4.63033784615655) * r + 1.42343711074968) / (((((((r * 0.00000000105075007164442 + 0.000547593808499535) * r + 0.0151986665636165) * r + 0.14810397642748) * r + 0.6897673349851) * r + 1.6763848301838) * r + 2.05319162663776) * r + 1) Else ' very close to 0 or 1 r += -5 val = (((((((r * 0.000000201033439929229 + 0.0000271155556874349) * r + 0.00124266094738808) * r + 0.0265321895265761) * r + 0.296560571828505) * r + 1.78482653991729) * r + 5.46378491116411) * r + 6.6579046435011) / (((((((r * 0.00000000000000204426310338994 + 0.000000142151175831645) * r + 0.0000184631831751005) * r + 0.000786869131145613) * r + 0.0148753612908506) * r + 0.136929880922736) * r + 0.599832206555888) * r + 1) End If If q < 0.0 Then val = -val End If End If Return mu + sigma * val End Function




Reply With Quote