コード例 #1
0
    def _ensure_fieldarray(params):
        """Ensures the given params are a ``FieldArray``.

        Parameters
        ----------
        params : dict, FieldArray, numpy.record, or numpy.ndarray
            If the given object is a dict, it will be converted to a
            FieldArray.

        Returns
        -------
        params : FieldArray
            The given values as a FieldArray.
        return_atomic : bool
            Whether or not functions run on the parameters should be returned
            as atomic types or not.
        """
        if isinstance(params, dict):
            return_atomic = not any(
                isinstance(val, numpy.ndarray) for val in params.values())
            params = FieldArray.from_kwargs(**params)
        elif isinstance(params, numpy.record):
            return_atomic = True
            params = FieldArray.from_records(tuple(params),
                                             names=params.dtype.names)
        elif isinstance(params, numpy.ndarray):
            return_atomic = False
            params = params.view(type=FieldArray)
        elif isinstance(params, FieldArray):
            return_atomic = False
        else:
            raise ValueError("params must be either dict, FieldArray, "
                             "record, or structured array")
        return params, return_atomic
コード例 #2
0
 def rvs(self, size=1):
     """ Rejection samples the parameter space.
     """
     # create output FieldArray
     dtype = [(arg, float) for arg in self.variable_args]
     out = FieldArray(size, dtype=dtype)
     # loop until enough samples accepted
     remaining = size
     ndraw = size
     while remaining:
         # scratch space for evaluating constraints
         scratch = FieldArray(ndraw, dtype=dtype)
         for dist in self.distributions:
             # drawing samples from the distributions is generally faster
             # then evaluating constrants, so we'll always draw the full
             # size, even if that gives us more points than we need
             draw = dist.rvs(size=ndraw)
             for param in dist.params:
                 scratch[param] = draw[param]
         # apply any constraints
         keep = self.contains(scratch)
         nkeep = keep.sum()
         kmin = size - remaining
         kmax = min(nkeep, remaining)
         out[kmin:kmin + kmax] = scratch[keep][:kmax]
         remaining = max(0, remaining - nkeep)
         # to try to speed up next go around, we'll increase the draw
         # size by the fraction of values that were kept, but cap at 1e6
         ndraw = int(min(1e6, ndraw * numpy.ceil(ndraw / (nkeep + 1.))))
     return out
コード例 #3
0
ファイル: joint.py プロジェクト: josh-willis/pycbc
    def _ensure_fieldarray(params):
        """Ensures the given params are a ``FieldArray``.

        Parameters
        ----------
        params : dict, FieldArray, numpy.record, or numpy.ndarray
            If the given object is a dict, it will be converted to a
            FieldArray.

        Returns
        -------
        FieldArray
            The given values as a FieldArray.
        """
        if isinstance(params, dict):
            return FieldArray.from_kwargs(**params)
        elif isinstance(params, numpy.record):
            return FieldArray.from_records(tuple(params),
                                           names=params.dtype.names)
        elif isinstance(params, numpy.ndarray):
            return params.view(type=FieldArray)
        elif isinstance(params, FieldArray):
            return params
        else:
            raise ValueError("params must be either dict, FieldArray, "
                             "record, or structured array")
コード例 #4
0
 def parse_known_args(self, args=None, namespace=None):
     """Parse args method to handle input-file dependent arguments."""
     # run parse args once to make sure the name space is populated with
     # the input files. We'll turn off raising NoInputFileErrors on this
     # pass
     self.no_input_file_err = True
     self._unset_required()
     opts, extra_opts = super(ResultsArgumentParser,
                              self).parse_known_args(args, namespace)
     # now do it again
     self.no_input_file_err = False
     self._reset_required()
     opts, extra_opts = super(ResultsArgumentParser,
                              self).parse_known_args(args, opts)
     # populate the parameters option if it wasn't specified
     if opts.parameters is None or opts.parameters == ['*']:
         parameters = get_common_parameters(opts.input_file,
                                            collection=self.defaultparams)
         # now call parse parameters action to re-populate the namespace
         self.actions['parameters'](self, opts, parameters)
     # check if we're being greedy or not
     elif '*' in opts.parameters:
         # remove the * from the parameters and the labels
         opts.parameters = [p for p in opts.parameters if p != '*']
         opts.parameters_labels.pop('*', None)
         # add the rest of the parameters not used
         all_params = get_common_parameters(opts.input_file,
                                            collection=self.defaultparams)
         # extract the used parameters from the parameters option
         used_params = FieldArray.parse_parameters(opts.parameters,
                                                   all_params)
         add_params = set(all_params) - set(used_params)
         # repopulate the name space with the additional parameters
         if add_params:
             opts.parameters += list(add_params)
             # update the labels
             opts.parameters_labels.update({p: p for p in add_params})
     # parse the sampler-specific options and check for any unknowns
     unknown = []
     for fn in opts.input_file:
         fp = loadfile(fn, 'r')
         sampler_parser, _ = fp.extra_args_parser(skip_args=self.skip_args)
         if sampler_parser is not None:
             opts, still_unknown = sampler_parser.parse_known_args(
                 extra_opts, namespace=opts)
             unknown.append(set(still_unknown))
     # the intersection of the unknowns are options not understood by
     # any of the files
     if len(unknown) > 0:
         unknown = set.intersection(*unknown)
     return opts, list(unknown)
コード例 #5
0
    def __init__(self, variable_args, *distributions, **kwargs):

        # store the names of the parameters defined in the distributions
        self.variable_args = tuple(variable_args)

        # store the distributions
        self.distributions = distributions

        # store the constraints on the parameters defined inside the
        # distributions list
        self._constraints = kwargs["constraints"] \
                                  if "constraints" in kwargs.keys() else []

        # store kwargs
        self.kwargs = kwargs

        # check that all of the supplied parameters are described by the given
        # distributions
        distparams = set()
        for dist in distributions:
            distparams.update(set(dist.params))

        varset = set(self.variable_args)
        missing_params = distparams - varset
        if missing_params:
            raise ValueError("provided variable_args do not include "
                             "parameters %s" % (','.join(missing_params)) +
                             " which are "
                             "required by the provided distributions")
        extra_params = varset - distparams
        if extra_params:
            raise ValueError("variable_args %s " % (','.join(extra_params)) +
                             "are not in any of the provided distributions")

        # if there are constraints then find the renormalization factor
        # since a constraint will cut out part of the space
        # do this by random sampling the full space and find the percent
        # of samples rejected
        n_test_samples = kwargs["n_test_samples"] \
                             if "n_test_samples" in kwargs else int(1e6)
        if self._constraints:
            logging.info("Renormalizing distribution for constraints")

            # draw samples
            samples = {}
            for dist in self.distributions:
                draw = dist.rvs(n_test_samples)
                for param in dist.params:
                    samples[param] = draw[param]
            samples = FieldArray.from_kwargs(**samples)

            # evaluate constraints
            result = self.contains(samples)

            # set new scaling factor for prior to be
            # the fraction of acceptances in random sampling of entire space
            self._pdf_scale = result.sum() / float(n_test_samples)
            if self._pdf_scale == 0.0:
                raise ValueError(
                    "None of the random draws for pdf "
                    "renormalization satisfied the constraints. "
                    " You can try increasing the 'n_test_samples' keyword.")

        else:
            self._pdf_scale = 1.0

        # since Distributions will return logpdf we keep the scale factor
        # in log scale as well for self.__call__
        self._logpdf_scale = numpy.log(self._pdf_scale)