mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-02 00:02:38 +02:00
speed ups for normal cdf
This commit is contained in:
parent
337bf67559
commit
1e30ffd730
7 changed files with 38 additions and 96 deletions
|
|
@ -23,7 +23,7 @@ def chain_1(df_dg, dg_dx):
|
|||
"""
|
||||
if np.all(dg_dx==1.):
|
||||
return df_dg
|
||||
if len(df_dg) > 1 and df_dg.shape[-1] > 1:
|
||||
if len(df_dg) > 1 and len(df_dg.shape)>1 and df_dg.shape[-1] > 1:
|
||||
import ipdb; ipdb.set_trace() # XXX BREAKPOINT
|
||||
raise NotImplementedError('Not implemented for matricies yet')
|
||||
return df_dg * dg_dx
|
||||
|
|
@ -37,7 +37,7 @@ def chain_2(d2f_dg2, dg_dx, df_dg, d2g_dx2):
|
|||
"""
|
||||
if np.all(dg_dx==1.) and np.all(d2g_dx2 == 0):
|
||||
return d2f_dg2
|
||||
if len(d2f_dg2) > 1 and d2f_dg2.shape[-1] > 1:
|
||||
if len(d2f_dg2) > 1 and len(d2f_dg2.shape)>1 and d2f_dg2.shape[-1] > 1:
|
||||
raise NotImplementedError('Not implemented for matricies yet')
|
||||
#dg_dx_2 = np.clip(dg_dx, 1e-12, _lim_val_square)**2
|
||||
dg_dx_2 = dg_dx**2
|
||||
|
|
|
|||
|
|
@ -1,77 +1,15 @@
|
|||
# Copyright (c) 2012, 2013 Ricardo Andrade
|
||||
# Copyright (c) 2015 James Hensman
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
import numpy as np
|
||||
from scipy import weave
|
||||
from scipy.special import ndtr as std_norm_cdf
|
||||
|
||||
#define a standard normal pdf
|
||||
_sqrt_2pi = np.sqrt(2*np.pi)
|
||||
def std_norm_pdf(x):
|
||||
"""Standard Gaussian density function"""
|
||||
return 1./np.sqrt(2.*np.pi)*np.exp(-.5*x**2)
|
||||
|
||||
def std_norm_cdf(x):
|
||||
"""
|
||||
Cumulative standard Gaussian distribution
|
||||
Based on Abramowitz, M. and Stegun, I. (1970)
|
||||
"""
|
||||
x_shape = np.asarray(x).shape
|
||||
|
||||
if len(x_shape) == 0 or x_shape[0] == 1:
|
||||
sign = np.sign(x)
|
||||
x *= sign
|
||||
x /= np.sqrt(2.)
|
||||
t = 1.0/(1.0 + 0.3275911*x)
|
||||
erf = 1. - np.exp(-x**2)*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429)))))
|
||||
cdf_x = 0.5*(1.0 + sign*erf)
|
||||
return cdf_x
|
||||
else:
|
||||
x = np.atleast_1d(x).copy()
|
||||
cdf_x = np.zeros_like(x)
|
||||
sign = np.ones_like(x)
|
||||
neg_x_ind = x<0
|
||||
sign[neg_x_ind] = -1.0
|
||||
x[neg_x_ind] = -x[neg_x_ind]
|
||||
x /= np.sqrt(2.)
|
||||
t = 1.0/(1.0 + 0.3275911*x)
|
||||
erf = 1. - np.exp(-x**2)*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429)))))
|
||||
cdf_x = 0.5*(1.0 + sign*erf)
|
||||
cdf_x = cdf_x.reshape(x_shape)
|
||||
return cdf_x
|
||||
|
||||
def std_norm_cdf_weave(x):
|
||||
"""
|
||||
Cumulative standard Gaussian distribution
|
||||
Based on Abramowitz, M. and Stegun, I. (1970)
|
||||
|
||||
A weave implementation of std_norm_cdf, which is faster. this is unused,
|
||||
because of the difficulties of a weave dependency. (see github issue #94)
|
||||
|
||||
"""
|
||||
#Generalize for many x
|
||||
x = np.asarray(x).copy()
|
||||
cdf_x = np.zeros_like(x)
|
||||
N = x.size
|
||||
support_code = "#include <math.h>"
|
||||
code = """
|
||||
|
||||
double sign, t, erf;
|
||||
for (int i=0; i<N; i++){
|
||||
sign = 1.0;
|
||||
if (x[i] < 0.0){
|
||||
sign = -1.0;
|
||||
x[i] = -x[i];
|
||||
}
|
||||
x[i] = x[i]/sqrt(2.0);
|
||||
|
||||
t = 1.0/(1.0 + 0.3275911*x[i]);
|
||||
|
||||
erf = 1. - exp(-x[i]*x[i])*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429)))));
|
||||
|
||||
//return_val = 0.5*(1.0 + sign*erf);
|
||||
cdf_x[i] = 0.5*(1.0 + sign*erf);
|
||||
}
|
||||
"""
|
||||
weave.inline(code, arg_names=['x', 'cdf_x', 'N'], support_code=support_code)
|
||||
return cdf_x
|
||||
return np.exp(-np.square(x)/2)/_sqrt_2pi
|
||||
|
||||
def inv_std_norm_cdf(x):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue