From 34658372fbc7a0a3e8bae4a79c1f2381d0b51a3f Mon Sep 17 00:00:00 2001 From: Antony Lewis Date: Thu, 25 Apr 2024 10:24:03 +0100 Subject: [PATCH] Simple implementation for vector parameters #191 --- CHANGELOG.md | 16 +++++------- cobaya/__init__.py | 2 +- cobaya/collection.py | 14 +++++++++-- cobaya/prior.py | 37 ++++++++++++++++++++++++++++ cobaya/samplers/minimize/minimize.py | 4 +-- cobaya/theories/classy/classy.py | 11 ++++++++- 6 files changed, 68 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e0ece52c..bcb783c5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ -## 3.x +## 3.5.1 + +### General + +- Use of vector parameters now documented (PR #191; inspired by @lukashergt, thanks!) ### Cosmology + - Added DESI 1yr BAO data and SN from Pantheon Plus, DESY5 and Union3 (thanks DESI team, @adematti, @rubind, @WillMatt4 and @rodri981) ## 3.5 – 2024-02-16 @@ -145,15 +150,6 @@ - Documented uses of `Model` class in general contexts (previously only cosmo) - `Model` methods to compute log-probabilities and derived parameters now have an `as_dict` keyword (default `False`), for more informative return value. -- Added `--minimize` flag to `cobaya-run` for quick minimization (replaces sampler, uses previous output). -- Add `COBAYA_USE_FILE_LOCKING` environment variable to allow disabling of file locks. Warning not to use `--test` with MPI. -- Installation of external packages is now version-aware for some packages; added `--upgrade` option to `cobaya-install`, off by default to preserve possible user changes. -- Introduced `cobaya.component.ComponentNotFoundError` to handle cases in which internal or external components cannot be found. -- In Linux terminals, added `COBAYA_COLOR` environment variable to get colourful output, useful e.g. for debugging, but *not* recommended for output to a file (e.g. running in a cluster). - -### PolyChord - -- Updated to v1.20.1: adds `nfail` to control failed initialisation, `synchronous` to choose sync/async parallelisation, variable number of live points, and the possibility to use an internal maximiser. Merges #232 (thanks @williamjameshandley). ### Cosmological likelihoods and theory codes diff --git a/cobaya/__init__.py b/cobaya/__init__.py index 864900f2c..7ede0e512 100644 --- a/cobaya/__init__.py +++ b/cobaya/__init__.py @@ -15,7 +15,7 @@ __author__ = "Jesus Torrado and Antony Lewis" -__version__ = "3.5" +__version__ = "3.5.1" __obsolete__ = False __year__ = "2024" __url__ = "https://cobaya.readthedocs.io" diff --git a/cobaya/collection.py b/cobaya/collection.py index f745362ef..2508c795a 100644 --- a/cobaya/collection.py +++ b/cobaya/collection.py @@ -458,8 +458,18 @@ def _cache_add_row(self, pos: int, values: Union[Sequence[float], np.ndarray], self._cache[pos, self._icol[name]] = -2 * value self._cache[pos, self._icol[OutPar.chi2]] = -2 * logposterior.loglike if len(logposterior.derived): - for name, value in zip(self.derived_params, logposterior.derived): - self._cache[pos, self._icol[name]] = value + try: + for name, value in zip(self.derived_params, logposterior.derived): + self._cache[pos, self._icol[name]] = value + except ValueError: + raise LoggedError( + self.log, "Was expecting float for derived parameter %r, but " + "got %r (type %r) instead. If you have defined this " + "parameter manually (e.g. with a 'lambda') either make " + "sure that it returns a number (or nan), or set " + "'derived: False' for this parameter, so that its value" + " is not stored in the sample.", + name, value, type(value).__class__) def _cache_dump(self): """ diff --git a/cobaya/prior.py b/cobaya/prior.py index a6bf9098f..5ad25d1e9 100644 --- a/cobaya/prior.py +++ b/cobaya/prior.py @@ -297,6 +297,43 @@ value: "lambda logx: np.exp(logx)" +Vector parameters +----------------- + +If your theory/likelihood takes an array of parameters as an argument, you can define the +individual components' priors separately, and then combine them into an array of any shape +using a dynamically defined parameter. + +Notice that the individual components must have +``drop: True`` in order not to be passed down the pipeline, and the dynamically-defined +vector must carry ``derived: False``, since only numbers, not arrays, can be saved as +derived parameters. + +You can see an example below, defining a Gaussian likelihood on the sum of two parameters, +which are taken as components of a single array-like argument: + + +.. code:: Python + + from scipy import stats + + + def gauss_band(x_vector): + return stats.norm.logpdf( + x_vector[0] + x_vector[1], loc=1, scale=0.02) + + # NB: don't forget the 'drop: True' in the individual parameters + # and 'derived: False' in the vector parameters + + info = { + "likelihood": {"band": gauss_band}, + "params": { + "x": {"prior": {"min": 0, "max": 2}, "proposal": 0.1, "drop": True}, + "y": {"prior": {"min": 0, "max": 2}, "proposal": 0.1, "drop": True}, + "x_vector": {"value": lambda x, y: [x, y], "derived": False}}, + "sampler": {"mcmc": None}} + + .. _prior_inheritance: Changing and redefining parameters; inheritance diff --git a/cobaya/samplers/minimize/minimize.py b/cobaya/samplers/minimize/minimize.py index 316972b9d..4257f71bb 100644 --- a/cobaya/samplers/minimize/minimize.py +++ b/cobaya/samplers/minimize/minimize.py @@ -267,7 +267,7 @@ def minuslogp_transf(x): self.log.debug("Starting point: %r", initial_point) self._affine_transform_baseline = initial_point initial_point = self.affine_transform(initial_point) - np.testing.assert_allclose(initial_point, np.zeros(initial_point.shape)) + assert np.allclose(initial_point, 0.) bounds = np.array( [self.affine_transform(self._bounds[:, i]) for i in range(2)]).T try: @@ -444,7 +444,7 @@ def products(self): "X0": self._affine_transform_baseline} def getdist_point_text(self, params, weight=None, minuslogpost=None): - """Creates the multi-line string containing the minumum in GetDist format.""" + """Creates the multi-line string containing the minimum in GetDist format.""" lines = [] if weight is not None: lines.append(' weight = %s' % weight) diff --git a/cobaya/theories/classy/classy.py b/cobaya/theories/classy/classy.py index ea4625ba7..fa405b068 100644 --- a/cobaya/theories/classy/classy.py +++ b/cobaya/theories/classy/classy.py @@ -95,6 +95,15 @@ sense to add it. +String-vector parameters +^^^^^^^^^^^^^^^^^^^^^^^^ + +At the time of writing, the CLASS Python interface takes some vector-like parameters +as string in which different components are separater by a space. To be able to set priors +or fixed values on each components, see `this trick +`_, and don't +forget the ``derived: False`` in the vector parameter (thanks to Lukas Hergt). + .. _classy_modify: Modifying CLASS @@ -102,7 +111,7 @@ If you modify CLASS and add new variables, make sure that the variables you create are exposed in the Python interface -(`instructions here `__). +(`instructions here `_). If you follow those instructions you do not need to make any additional modification in Cobaya.