Beispiel #1
0
def uniform(nmr_distributions,
            nmr_samples,
            low=0,
            high=1,
            ctype='float',
            seed=None):
    """Draw random samples from the Uniform distribution.

    Args:
        nmr_distributions (int): the number of unique continuous_distributions to create
        nmr_samples (int): The number of samples to draw
        low (double): The minimum value of the random numbers
        high (double): The minimum value of the random numbers
        ctype (str): the C type of the output samples
        seed (float): the seed for the RNG

    Returns:
        ndarray: A two dimensional numpy array as (nmr_distributions, nmr_samples).
    """
    if is_scalar(low):
        low = np.ones((nmr_distributions, 1)) * low
    if is_scalar(high):
        high = np.ones((nmr_distributions, 1)) * high

    kernel_data = {
        'low': Array(low, as_scalar=True),
        'high': Array(high, as_scalar=True)
    }

    kernel = SimpleCLFunction.from_string(
        '''
        void compute(double low, double high, global uint* rng_state, global '''
        + ctype + '''* samples){
        
            rand123_data rand123_rng_data = rand123_initialize_data((uint[]){
                rng_state[0], rng_state[1], rng_state[2], rng_state[3], 
                rng_state[4], rng_state[5], 0});
            void* rng_data = (void*)&rand123_rng_data;

            for(uint i = 0; i < ''' + str(nmr_samples) + '''; i++){
                double4 randomnr = rand4(rng_data);
                samples[i] = (''' + ctype +
        ''')(low + randomnr.x * (high - low));
            }
        }
    ''',
        dependencies=[Rand123()])

    return _generate_samples(kernel,
                             nmr_distributions,
                             nmr_samples,
                             ctype,
                             kernel_data,
                             seed=seed)
Beispiel #2
0
    def item_generator():
        for ind in range(samples.shape[0]):
            if is_scalar(lower_bounds):
                lower_bound = lower_bounds
            else:
                lower_bound = lower_bounds[ind]

            if is_scalar(upper_bounds):
                upper_bound = upper_bounds
            else:
                upper_bound = upper_bounds[ind]

            yield (samples[ind], lower_bound, upper_bound)
Beispiel #3
0
def normal(nmr_distributions,
           nmr_samples,
           mean=0,
           std=1,
           ctype='float',
           seed=None):
    """Draw random samples from the Gaussian distribution.

    Args:
        nmr_distributions (int): the number of unique continuous_distributions to create
        nmr_samples (int): The number of samples to draw
        mean (float or ndarray): The mean of the distribution
        std (float or ndarray): The standard deviation or the distribution
        ctype (str): the C type of the output samples
        seed (float): the seed for the RNG

    Returns:
        ndarray: A two dimensional numpy array as (nmr_distributions, nmr_samples).
    """
    if is_scalar(mean):
        mean = np.ones((nmr_distributions, 1)) * mean
    if is_scalar(std):
        std = np.ones((nmr_distributions, 1)) * std

    kernel_data = {
        'mean': Array(mean, as_scalar=True),
        'std': Array(std, as_scalar=True)
    }

    kernel = SimpleCLFunction.from_string('''
        void compute(double mean, double std, global uint* rng_state, global '''
                                          + ctype + '''* samples){
            rand123_data rand123_rng_data = rand123_initialize_data((uint[]){
                rng_state[0], rng_state[1], rng_state[2], rng_state[3], 
                rng_state[4], rng_state[5], 0});
            void* rng_data = (void*)&rand123_rng_data;

            for(uint i = 0; i < ''' + str(nmr_samples) + '''; i++){
                double4 randomnr = randn4(rng_data);
                samples[i] = (''' + ctype + ''')(mean + randomnr.x * std);
            }
        }
    ''',
                                          dependencies=[Rand123()])

    return _generate_samples(kernel,
                             nmr_distributions,
                             nmr_samples,
                             ctype,
                             kernel_data,
                             seed=seed)
Beispiel #4
0
    def run(self, args, extra_args):
        if args.output_file is not None:
            output_file = os.path.realpath(args.output_file)
        else:
            output_file = os.path.realpath(args.input_protocol)

        additional_files = []
        if args.additional_files:
            for file in args.additional_files:
                additional_files.append(np.genfromtxt(file))

        protocol = mdt.load_protocol(os.path.realpath(args.input_protocol))
        context_dict = {
            name: protocol.get_column(name)
            for name in protocol.column_names
        }

        exec(args.expr, {'np': np, 'files': additional_files}, context_dict)

        for key in context_dict:
            if is_scalar(context_dict[key]):
                context_dict[key] = np.ones(
                    protocol.length) * context_dict[key]

        protocol = Protocol(context_dict)
        mdt.write_protocol(protocol, output_file)
Beispiel #5
0
 def test_is_scalar(self):
     self.assertTrue(is_scalar(np.zeros((1, ))[:, None]))
     self.assertTrue(is_scalar(np.zeros((1,))))
     self.assertTrue(is_scalar(-1))
     self.assertTrue(is_scalar(0))
     self.assertTrue(is_scalar(1))
     self.assertTrue(is_scalar(-1.0))
     self.assertTrue(is_scalar(0.0))
     self.assertTrue(is_scalar(1.0))
Beispiel #6
0
            def get_data_object(param):
                if input_data[param.name] is None:
                    return Scalar(0)
                elif isinstance(input_data[param.name], KernelData):
                    return input_data[param.name]
                elif param.data_type.is_vector_type and np.squeeze(
                        input_data[param.name]).shape[0] == 3:
                    return Scalar(input_data[param.name],
                                  ctype=param.data_type.ctype)
                elif is_scalar(input_data[
                        param.name]) and not param.data_type.is_pointer_type:
                    return Scalar(input_data[param.name])
                else:
                    if is_scalar(input_data[param.name]):
                        data = np.ones(nmr_instances) * input_data[param.name]
                    else:
                        data = input_data[param.name]

                    return Array(data, ctype=param.data_type.ctype, mode='rw')
Beispiel #7
0
 def test_is_not_scalar(self):
     self.assertFalse(is_scalar(np.zeros((2, 2))))
Beispiel #8
0
    def __init__(self,
                 ll_func,
                 log_prior_func,
                 x0,
                 proposal_stds,
                 waiting_period=100,
                 scaling_factor=2.4,
                 epsilon=1e-5,
                 **kwargs):
        r"""An implementation of the Single Component Adaptive Metropolis (SCAM) MCMC algorithm [1].

        The SCAM method works by adapting the proposal standard deviation to the empirical standard deviation of the
        component's marginal distribution. That is, the standard deviation :math:`\sigma_i^{(t)}` for the proposal
        distribution of the :math:`i` th component at time :math:`t` is given by:

        .. math::

            \sigma_i^{(t)} = \begin{cases}
            \sigma_i^{(0)}, & t \leq t_s \\
            2.4 * \sqrt{\mathrm{Var}(\mathbf{X}^{(0)}_i, \ldots, \mathbf{X}^{(t-1)}_i)} + 1\cdot \epsilon, & t > t_s
            \end{cases}


        where :math:`t_s` denotes the iteration after which the adaptation starts (we use :math:`t_s = 100`).
        A small constant is necessary to prevent the standard deviation from shrinking to zero.
        This adaptation algorithm has been proven to retain ergodicity, meaning it is guaranteed to converge to the
        right stationary distribution [1].

        Args:
            ll_func (mot.lib.cl_function.CLFunction): The log-likelihood function. See parent docs.
            log_prior_func (mot.lib.cl_function.CLFunction): The log-prior function. See parent docs.
            x0 (ndarray): the starting positions for the sampler. Should be a two dimensional matrix
                with for every modeling instance (first dimension) and every parameter (second dimension) a value.
            proposal_stds (ndarray): for every parameter and every modeling instance an initial proposal std.
            waiting_period (int): only start updating the proposal std. after this many draws.
            scaling_factor (float): the scaling factor to use (the parameter ``s`` in the paper referenced).
            epsilon (float or ndarray): small number to prevent the std. from collapsing to zero.
                Can either be one value for all parameters, or one value per parameter.

        References:
            [1] Haario, H., Saksman, E., & Tamminen, J. (2005). Componentwise adaptation for high dimensional MCMC.
                Computational Statistics, 20(2), 265-273. https://doi.org/10.1007/BF02789703
        """
        super().__init__(ll_func, log_prior_func, x0, proposal_stds, **kwargs)
        self._waiting_period = waiting_period
        self._scaling_factor = scaling_factor
        self._epsilon = epsilon

        if is_scalar(self._epsilon):
            self._epsilon = np.ones(x0.shape[1]) * self._epsilon

        self._parameter_means = np.zeros(
            (self._nmr_problems, self._nmr_params),
            dtype=self._cl_runtime_info.mot_float_dtype,
            order='C')
        self._parameter_variances = np.zeros(
            (self._nmr_problems, self._nmr_params),
            dtype=self._cl_runtime_info.mot_float_dtype,
            order='C')
        self._parameter_variance_update_m2s = np.zeros(
            (self._nmr_problems, self._nmr_params),
            dtype=self._cl_runtime_info.mot_float_dtype,
            order='C')