def _rescaled_cvar(self, x):

        return C_CALL.empirical_cvar_py_interface(
            np.int32(x), np.int32(self.n), np.int32(self.gen.min),
            np.int32(self.gen.max), ffi.cast("int *",
                                             self.nd_vals.ctypes.data),
            ffi.cast("double *", self.gen.cdf_vals.ctypes.data),
            ffi.cast("double *", self.gen.expectation_vals.ctypes.data))
    def _rescaled_cvar(self, x):

        cvar = C_CALL.semiparametric_cvar_py_interface(
            np.int32(x), np.float64(self.u), np.float64(self.p),
            np.float64(self.sigma), np.float64(self.xi), np.int32(self.n),
            np.int32(self.gen.min), np.int32(self.gen.max),
            ffi.cast("int *", self.nd_vals.ctypes.data),
            ffi.cast("double *", self.gen.cdf_vals.ctypes.data),
            ffi.cast("double *", self.gen.expectation_vals.ctypes.data))

        if cvar == -1:
            cvar = np.Inf

        return cvar
    def cdf(self, m):
        """calculate margin CDF values

    **Parameters**:
    
    `m` (`float`): point to evaluate on

    """
        return C_CALL.semiparametric_power_margin_cdf_py_interface(
            np.int32(m), np.float64(self.u), np.float64(self.p),
            np.float64(self.sigma), np.float64(self.xi), np.int32(self.n),
            np.int32(self.gen.min), np.int32(self.gen.max),
            ffi.cast("int *", self.nd_vals.ctypes.data),
            ffi.cast("double *", self.gen.cdf_vals.ctypes.data))
    def cdf(self, x):
        """calculate margin CDF values

    **Parameters**:
    
    `x` (`numpy.ndarray`): point to evaluate on

    """
        if x >= self.max:
            return 1.0
        elif x < self.min:
            return 0.0
        else:
            return C_CALL.empirical_power_margin_cdf_py_interface(
                np.int32(x), np.int32(self.n), np.int32(self.gen.min),
                np.int32(self.gen.max),
                ffi.cast("int *", self.nd_vals.ctypes.data),
                ffi.cast("double *", self.gen.cdf_vals.ctypes.data))
    def cvar_trace(self, x):
        """calculate cvar values for each posterior parameter sample

    **Parameters**:
    
    `x` (`float`): absolute value of power margin shortfall's lower bound

    """
        if x < 0:
            raise Exception("x must be a non-negative number.")

        output = np.ascontiguousarray(np.empty((self.n_posterior, )),
                                      dtype=np.float64)

        C_CALL.bayesian_semiparametric_cvar_trace_py_interface(
            np.int32(x), np.float64(self.u), np.float64(self.p),
            np.int32(self.n_posterior),
            ffi.cast("double *", self.posterior_sigma.ctypes.data),
            ffi.cast("double *", self.posterior_xi.ctypes.data),
            np.int32(self.n), np.int32(self.gen.min), np.int32(self.gen.max),
            ffi.cast("int *", self.nd_vals.ctypes.data),
            ffi.cast("double *", self.gen.cdf_vals.ctypes.data),
            ffi.cast("double *", self.gen.expectation_vals.ctypes.data),
            ffi.cast("double *", output.ctypes.data))

        if output[0] == -1:
            raise Exception(
                "cvar is unbounded; some posterior shape samples are larger than 1"
            )
        else:
            return output
    def cdf_trace(self, x):
        """calculate margin CDF values for each posterior parameter sample

    **Parameters**:
    
    `x` (`float`): point to evaluate on

    """

        output = np.ascontiguousarray(np.empty((self.n_posterior, )),
                                      dtype=np.float64)

        C_CALL.bayesian_semiparametric_power_margin_cdf_trace_py_interface(
            np.int32(m), np.float64(self.u), np.float64(self.p),
            np.int32(self.n_posterior),
            ffi.cast("double *", self.posterior_sigma.ctypes.data),
            ffi.cast("double *", self.posterior_xi.ctypes.data),
            np.int32(self.n), np.int32(self.gen.min), np.int32(self.gen.max),
            ffi.cast("int *", self.nd_vals.ctypes.data),
            ffi.cast("double *", self.gen.cdf_vals.ctypes.data),
            ffi.cast("double *", output.ctypes.data))

        return output
    def __init__(self, gen, nd_data, u, sigma, xi):

        super().__init__(gen, nd_data)
        self.gen = gen
        self.n = len(self.nd_vals)

        self.u = u

        self.sigma = sigma

        #if np.abs(xi) < 1e-8: #to avoid numerical instability
        #  xi = 0

        self.xi = xi

        self.p = C_CALL.empirical_net_demand_cdf_py_interface(
            np.float64(self.u), np.int32(self.n),
            ffi.cast("int *", self.nd_vals.ctypes.data))