2010-10-13 22 views
2

我需要在MySQL中使用反常規累積分佈函數(在Excel中是NORMSINV函數),但是在那裏沒有這樣的函數。也許你們中的任何一個都有MySQL的實現?在MySQL中執行NORMSINV函數

非常感謝您的時間。

回答

1

嗯,我終於找到了這個。這不是完美的,但相當好的aproximation。代碼不是我的,它的作者是Geoffrey C. Barnes。我剛剛將它從VB.NET轉換爲MySQL。

DROP FUNCTION IF EXISTS NORMSINV; 
DELIMITER // 

CREATE FUNCTION NORMSINV (p DOUBLE) RETURNS DOUBLE 
BEGIN 

DECLARE q, r DOUBLE; 
DECLARE A1, A2, A3, A4, A5, A6 DOUBLE; 
DECLARE B1, B2, B3, B4, B5 DOUBLE; 
DECLARE C1, C2, C3, C4, C5, C6 DOUBLE; 
DECLARE D1, D2, D3, D4 DOUBLE; 
DECLARE P_LOW, P_HIGH DOUBLE; 

/* coefficients in rational approximations */ 
SET A1 = -39.696830286653757; 
SET A2 = 220.9460984245205; 
SET A3 = -275.92851044696869; 
SET A4 = 138.357751867269; 
SET A5 = -30.66479806614716; 
SET A6 = 2.5066282774592392; 

SET B1 = -54.476098798224058; 
SET B2 = 161.58583685804089; 
SET B3 = -155.69897985988661; 
SET B4 = 66.80131188771972; 
SET B5 = -13.280681552885721; 

SET C1 = -0.0077848940024302926; 
SET C2 = -0.32239645804113648; 
SET C3 = -2.4007582771618381; 
SET C4 = -2.5497325393437338; 
SET C5 = 4.3746641414649678; 
SET C6 = 2.9381639826987831; 

SET D1 = 0.0077846957090414622; 
SET D2 = 0.32246712907003983; 
SET D3 = 2.445134137142996; 
SET D4 = 3.7544086619074162; 

/* define break points */ 
SET P_LOW = 0.02425; 
SET P_HIGH = 1 - P_LOW; 

IF (p > 0 AND p < P_LOW) THEN 
/* rational approximation for lower region */ 
SET q = SQRT(-2 * LOG(p)); 
RETURN (((((C1 * q + C2) * q + C3) * q + C4) * q + C5) * q + C6)/ 
     ((((D1 * q + D2) * q + D3) * q + D4) * q + 1); 

ELSEIF (p >= P_LOW AND p <= P_HIGH) THEN 
/* rational approximation for central region */ 
SET q = p - 0.5; 
SET r = q * q; 
RETURN (((((A1 * r + A2) * r + A3) * r + A4) * r + A5) * r + A6) * q/
     (((((B1 * r + B2) * r + B3) * r + B4) * r + B5) * r + 1); 

ELSEIF (p > P_HIGH AND p < 1) THEN 
/* rational approximation for upper region */ 
SET q = SQRT(-2 * LOG(1 - p)); 
RETURN -(((((C1 * q + C2) * q + C3) * q + C4) * q + C5) * q + C6)/
     ((((D1 * q + D2) * q + D3) * q + D4) * q + 1); 

/* on error returning 0 */   
ELSE 
RETURN 0; 
END IF; 

END// 
DELIMITER ;