importnumpyasnpfromscipy.specialimporterfinv,erflog2PI=np.log(2.0*np.pi)"""Scipy's implementation of ERF: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.erf.htmlSee notes there for cumulative of the unit normal distribution."""
[docs]deftransform_to_probit(x,bounds):""" Coordinate change into probit space. cdf_normal is the cumulative distribution function of the unit normal distribution. WARNING: returns NAN if x is not in [xmin, xmax]. t(x) = cdf^-1_normal((x-x_min)/(x_max - x_min)) Arguments: np.ndarray x: sample(s) to transform (2d array) np.ndarray bounds: limits for each dimension (2d array, [[xmin, xmax], [ymin, ymax]...]) Returns: np.ndarray: sample(s) """dbounds=bounds[:,1]-bounds[:,0]sigma=dbounds*0.34cdf=(x-bounds[:,0])/dboundso=np.sqrt(2.0)*erfinv(2*cdf-1)*sigmareturno
[docs]deftransform_from_probit(x,bounds):""" Coordinate change from probit to natural space. cdf_normal is the cumulative distribution function of the unit normal distribution. x(t) = xmin + (xmax-xmin)*cdf_normal(t|0,1) Arguments: np.ndarray x: sample(s) to antitransform (2d array) np.ndarray bounds: limits for each dimension (2d array, [[xmin, xmax], [ymin, ymax]...]) Returns: np.ndarray: sample(s) """dbounds=bounds[:,1]-bounds[:,0]sigma=dbounds*0.34cdf=0.5*(1.0+erf(x/(np.sqrt(2.0)*sigma)))o=bounds[:,0]+dbounds*cdfreturno
[docs]defprobit_log_jacobian(x,bounds,flag=True):""" Jacobian of the probit transformation Arguments: np.ndarray x: sample(s) to evaluate the jacobian at np.ndarray bounds: limits for each dimension (2d array, [[xmin, xmax], [ymin, ymax]...]) bool flag: whether to skip the evaluation Returns: np.ndarray: log jacobian (zeros if flag is False) """ifnotflag:returnnp.zeros(len(x))dbounds=bounds[:,1]-bounds[:,0]sigma=dbounds*0.34res=-0.5*(x/sigma)**2-0.5*(log2PI)+np.log(dbounds)-np.log(sigma)returnres
[docs]defprobit_logJ(x,bounds,flag=True):""" Jacobian of the probit transformation marginalised over dimensions Arguments: np.ndarray x: sample(s) to evaluate the jacobian at np.ndarray bounds: limits for each dimension (2d array, [[xmin, xmax], [ymin, ymax]...]) bool flag: whether to skip the evaluation Returns: np.ndarray: log jacobian (zeros if flag is False) """ifnotflag:returnnp.zeros(len(x))dbounds=bounds[:,1]-bounds[:,0]sigma=dbounds*0.34res=np.sum(-0.5*(x/sigma)**2-0.5*log2PI+np.log(dbounds)-np.log(sigma),axis=-1)returnres
[docs]defgradient_inv_jacobian(x,bounds,flag=True):""" logarithmic gradient of the probit transformation Jacobian Arguments: np.ndarray x: sample(s) to evaluate the jacobian at np.ndarray bounds: limits for each dimension (2d array, [[xmin, xmax], [ymin, ymax]...]) bool flag: whether to skip the evaluation Returns: np.ndarray: log jacobian (ones if flag is False) """ifnotflag:returnnp.ones(len(x))dbounds=bounds[:,1]-bounds[:,0]sigma=dbounds*0.34returnx/sigma**2.