diff --git a/pkpd/__init__.py b/pkpd/__init__.py
index bc620e0..52948fa 100644
--- a/pkpd/__init__.py
+++ b/pkpd/__init__.py
@@ -9,7 +9,8 @@ import os
 
 from ._likelihoods import (  # noqa
     ConstantAndMultiplicativeGaussianLogLikelihood,
-    FixedEtaLogLikelihoodWrapper
+    FixedEtaLogLikelihoodWrapper,
+    PooledLogPDF
 )
 
 from ._models import (  # noqa
diff --git a/pkpd/_likelihoods.py b/pkpd/_likelihoods.py
index d5c1e93..043afa7 100644
--- a/pkpd/_likelihoods.py
+++ b/pkpd/_likelihoods.py
@@ -273,3 +273,173 @@ class FixedEtaLogLikelihoodWrapper(pints.LogPDF):
 
     def n_parameters(self):
         return self._log_pdf.n_parameters() - 1
+
+
+class PooledLogPDF(pints.LogPDF):
+    r"""
+    Calculates a sum of :class:`LogPDF` objects, while pooling selected
+    parameters across log-pdfs.
+
+    This :class:`LogPDF` requires that all :class:`LogPDF` objects have the
+    same number of parameters.
+
+    This is useful for e.g. modelling the time-series of multiple individuals
+    (each individual defines a separate :class:`LogPDF`), and some parameters
+    are expected to be the same across individuals. This may be a realistic
+    expectation for the noise parameter, if the experimental set up didn't vary
+    for the indiviudals.
+
+    For two :class:`LogPDF` objects :math:`L _1`  and :math:`L _2` with
+    parameters :math:`(\psi _1, \theta _1`) and :math:`(\psi _2, \theta _2`)
+    respectively, a pooling of the :math:`\theta _i` results in a pooled
+    log-pdf of the form
+
+    .. math::
+        \log L(\psi _1, \psi _2, \theta | D_1, D_2) =
+            \log L(\psi _1, \theta | D_1) + \log L(\psi _2, \theta | D_2),
+
+    where :math:`\theta := \theta _1 = \theta _2`, and $D_i$ is the measured
+    time-series of individual :math:`i`.
+
+    In general, the search of a :class:`PooledLogPDF` has dimensionality
+    :math:`nd_{\text{up}} + d_{\text{p}}`, where :math:`n` is the number of
+    individuals, :math:`d_{\text{up}}` is the dimension of the unpooled
+    :math:`psi` parameters, and :math:`d_{\text{up}}` is the dimension of the
+    pooled :math:`\theta` parameter.
+
+    The order of parameters for evaluation is largely kept, and the parameters
+    of individual log-pdfs are concatenated. However, pooled parameters are
+    always prepended. Consider for example two log-pdf with parameters
+    :math:`(\psi _{1,1}, \psi _{1, 2}, \psi _{1,3}, \psi _{1,4})` and
+    :math:`(\psi _{2,1}, \psi _{2, 2}, \psi _{2,3}, \psi _{2,4})`. Pooling the
+    first and the last parameter, i.e.
+    :math:`\theta _1 := \psi _{1,1} = \psi _{2, 1}` and
+    :math:`\theta _4 := \psi _{1,4} = \psi _{2, 4}` results in and expect
+    order of parameters
+    :math:`(\psi _{1, 2}, \psi _{1,3}, \psi _{2, 2}, \psi _{2,3}, \theta _1,
+    \theta _4)`.
+
+    Extends :class:`LogPDF`.
+
+    Parameters
+    ----------
+    log_pdfs
+        A sequence of :class:`LogPDF` objects.
+    pooled
+        An array-like object of dtype bool, indicating which parameters across
+        the likelihoods are pooled (`True`) or remain unpooled (`False`).
+
+    Example
+    -------
+    ::
+        pooled_log_likelihood = pints.PooledLogPDFs(
+            log_pdfs=[
+                pints.GaussianLogLikelihood(problem1),
+                pints.GaussianLogLikelihood(problem2)],
+            pooled=[False, True])
+    """
+    def __init__(self, log_pdfs, pooled):
+        super(PooledLogPDF, self).__init__()
+
+        # Check input arguments
+        if len(log_pdfs) < 2:
+            raise ValueError(
+                'PooledLogPDF requires at least two log-pdfs.')
+        for index, pdf in enumerate(log_pdfs):
+            if not isinstance(pdf, pints.LogPDF):
+                raise ValueError(
+                    'All log-pdfs passed to PooledLogPDFs must be instances of'
+                    ' pints.LogPDF (failed on argument '
+                    + str(index) + ').')
+
+        # Check parameter dimension across log-pdfs
+        self._log_pdfs = log_pdfs
+        n_parameters = self._log_pdfs[0].n_parameters()
+        for pdf in self._log_pdfs:
+            if pdf.n_parameters() != n_parameters:
+                raise ValueError(
+                    'All log-pdfs passed to PooledLogPDFs must have '
+                    'same dimension.')
+
+        # Check that pooled matches number of parameters
+        self._pooled = np.asarray(pooled)
+        if len(self._pooled) != n_parameters:
+            raise ValueError(
+                'The array-like input `pooled` needs to have the same length '
+                'as the number of parameters of the individual log-pdfs.')
+
+        # Check that pooled contains only booleans
+        for p in self._pooled:
+            if not isinstance(p, np.bool_):
+                raise ValueError(
+                    'The array-like input `pooled` passed to PooledLogPDFs '
+                    'has to contain booleans exclusively.')
+
+        # Get dimension of search space
+        self._n_pooled = np.sum(self._pooled)
+        n_individuals = len(self._log_pdfs)
+        self._n_unpooled = np.sum(~self._pooled)
+        self._n_parameters = \
+            self._n_pooled + n_individuals * self._n_unpooled
+
+    def __call__(self, parameters):
+        # Get parameters of pooled log-pdf
+        parameters = np.asarray(parameters)
+
+        # Create container for parameters of individuals log-pdf and fill with
+        # pooled parameters
+        params_ind = np.empty(shape=self._n_unpooled + self._n_pooled)
+        if self._n_pooled > 0:
+            params_ind[self._pooled] = parameters[-self._n_pooled:]
+
+        # Compute pdf score
+        total = 0
+        for idx, pdf in enumerate(self._log_pdfs):
+            # Get unpooled parameters for individual
+            params_ind[~self._pooled] = parameters[
+                idx * self._n_unpooled: (idx + 1) * self._n_unpooled]
+
+            # Compute pdf score contribution
+            total += pdf(params_ind)
+        return total
+
+    def evaluateS1(self, parameters):
+        """
+        See :meth:`LogPDF.evaluateS1()`.
+
+        *This method only works if all the underlying :class:`LogPDF` objects
+        implement the optional method :meth:`LogPDF.evaluateS1()`!*
+        """
+        # Get parameters of pooled log-pdf
+        parameters = np.asarray(parameters)
+
+        # Create container for parameters of individuals log-pdf and fill with
+        # pooled parameters
+        params_ind = np.empty(shape=self._n_unpooled + self._n_pooled)
+        if self._n_pooled > 0:
+            params_ind[self._pooled] = parameters[-self._n_pooled:]
+
+        # Compute pdf score and partials
+        total = 0
+        dtotal = np.zeros(shape=self._n_parameters)
+        for idx, pdf in enumerate(self._log_pdfs):
+            # Get unpooled parameters for individual
+            params_ind[~self._pooled] = parameters[
+                idx * self._n_unpooled: (idx + 1) * self._n_unpooled]
+
+            # Compute pdf score and partials for individual
+            score, partials = pdf.evaluateS1(params_ind)
+
+            # Add contributions to score and partials. Note that partials
+            # w.r.t. unpooled parameters receive only one contribution
+            total += score
+            dtotal[idx * self._n_unpooled: (idx + 1) * self._n_unpooled] = \
+                partials[~self._pooled]
+            if self._n_pooled > 0:
+                dtotal[-self._n_pooled:] += partials[self._pooled]
+
+        return total, dtotal
+
+    def n_parameters(self):
+        """ See :meth:`LogPDF.n_parameters()`. """
+        return self._n_parameters

SharedNoiseLogLikelihood
Implemement a pints.LogPDF that allows to share the noise parameters between problems.
diff --git a/pkpd/tests/test_likelihoods.py b/pkpd/tests/test_likelihoods.py
index 90fac88..9a5b564 100644
--- a/pkpd/tests/test_likelihoods.py
+++ b/pkpd/tests/test_likelihoods.py
@@ -617,5 +617,220 @@ class TestFixedEtaLogLikelihoodWrapper(unittest.TestCase):
         self.assertEqual(wrapped_log_likelihood.n_parameters(), 2)
 
 
+class TestPooledLogPDF(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        # Create test log-pdfs
+        model = pints.toy.ConstantModel(1)
+
+        problem = pints.SingleOutputProblem(
+            model=model, times=[1, 2, 3, 4], values=[1, 2, 3, 4])
+        cls.log_pdf_1 = pints.GaussianLogLikelihood(problem)
+
+        problem = pints.SingleOutputProblem(
+            model=model, times=[1, 2, 3, 4], values=[1, 1, 1, 1])
+        cls.log_pdf_2 = pints.GaussianLogLikelihood(problem)
+
+    def test_bad_number_log_pdfs(self):
+        log_pdfs = [self.log_pdf_1]
+        pooled = [True, True]
+        self.assertRaisesRegex(
+            ValueError, 'PooledLogPDF requires', pkpd.PooledLogPDF, log_pdfs,
+            pooled)
+
+    def test_bad_log_pdfs_objects(self):
+        log_pdfs = ['log_pdf_1', 'log_pdf_2']
+        pooled = [True, True]
+        self.assertRaisesRegex(
+            ValueError, 'All log-pdfs passed', pkpd.PooledLogPDF, log_pdfs,
+            pooled)
+
+    def test_bad_log_pdfs_parameters(self):
+        model = pints.toy.ConstantModel(1)
+        problem = pints.SingleOutputProblem(
+            model=model, times=[1, 2, 3, 4], values=[1, 2, 3, 4])
+        log_pdf = pkpd.ConstantAndMultiplicativeGaussianLogLikelihood(problem)
+
+        log_pdfs = [self.log_pdf_1, log_pdf]
+        pooled = [True, True]
+
+        self.assertRaisesRegex(
+            ValueError, 'All log-pdfs passed to PooledLogPDFs',
+            pkpd.PooledLogPDF, log_pdfs, pooled)
+
+    def test_bad_pooled_length(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [True, True, True]
+        self.assertRaisesRegex(
+            ValueError, 'The array-like input `pooled` needs',
+            pkpd.PooledLogPDF, log_pdfs, pooled)
+
+    def test_bad_pooled_content(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [True, 'Yes']
+        self.assertRaisesRegex(
+            ValueError, 'The array-like input `pooled` passed',
+            pkpd.PooledLogPDF, log_pdfs, pooled)
+
+    def test_n_parameters(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+
+        # Pool nothing
+        pooled = [False, False]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        n_parameters = \
+            self.log_pdf_1.n_parameters() + self.log_pdf_2.n_parameters()
+        self.assertEqual(log_pdf.n_parameters(), n_parameters)
+
+        # Pool first parameter
+        pooled = [True, False]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        n_parameters = 2 * 1 + 1
+        self.assertEqual(log_pdf.n_parameters(), n_parameters)
+
+        # Pool second parameter
+        pooled = [False, True]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        n_parameters = 2 * 1 + 1
+        self.assertEqual(log_pdf.n_parameters(), n_parameters)
+
+        # Pool both parameters
+        pooled = [True, True]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        n_parameters = 2 * 1
+        self.assertEqual(log_pdf.n_parameters(), n_parameters)
+
+    def test_call_unpooled(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [False, False]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.2]
+        param_2 = [2, 0.1]
+
+        score = self.log_pdf_1(param_1) + self.log_pdf_2(param_2)
+        self.assertEqual(log_pdf(param_1 + param_2), score)
+
+    def test_call_partially_pooled(self):
+        # Pool first parameter
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [True, False]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.2]
+        param_2 = [1, 0.1]
+        param = [0.2, 0.1, 1]
+
+        score = self.log_pdf_1(param_1) + self.log_pdf_2(param_2)
+        self.assertEqual(log_pdf(param), score)
+
+        # Pool second parameter
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [False, True]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.1]
+        param_2 = [2, 0.1]
+        param = [1, 2, 0.1]
+
+        score = self.log_pdf_1(param_1) + self.log_pdf_2(param_2)
+        self.assertEqual(log_pdf(param), score)
+
+    def test_call_pooled(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [True, True]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param = [1, 0.1]
+
+        score = self.log_pdf_1(param) + self.log_pdf_2(param)
+        self.assertEqual(log_pdf(param), score)
+
+    def test_evaluateS1_unpooled(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [False, False]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.2]
+        param_2 = [2, 0.1]
+
+        score_1, dscore_1 = self.log_pdf_1.evaluateS1(param_1)
+        score_2, dscore_2 = self.log_pdf_2.evaluateS1(param_2)
+
+        score, dscore = log_pdf.evaluateS1(param_1 + param_2)
+        self.assertEqual(score, score_1 + score_2)
+
+        self.assertEqual(len(dscore), 4)
+        self.assertEqual(dscore[0], dscore_1[0])
+        self.assertEqual(dscore[1], dscore_1[1])
+        self.assertEqual(dscore[2], dscore_2[0])
+        self.assertEqual(dscore[3], dscore_2[1])
+
+    def test_evaluateS1_partially_pooled(self):
+        # Pool first parameter
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [True, False]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.2]
+        param_2 = [1, 0.1]
+        param = [0.2, 0.1, 1]
+
+        score_1, dscore_1 = self.log_pdf_1.evaluateS1(param_1)
+        score_2, dscore_2 = self.log_pdf_2.evaluateS1(param_2)
+
+        score, dscore = log_pdf.evaluateS1(param)
+        self.assertEqual(score, score_1 + score_2)
+
+        self.assertEqual(len(dscore), 3)
+        self.assertEqual(dscore[0], dscore_1[1])
+        self.assertEqual(dscore[1], dscore_2[1])
+        self.assertEqual(dscore[2], dscore_1[0] + dscore_2[0])
+
+        # Pool second parameter
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [False, True]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.1]
+        param_2 = [2, 0.1]
+        param = [1, 2, 0.1]
+
+        score_1, dscore_1 = self.log_pdf_1.evaluateS1(param_1)
+        score_2, dscore_2 = self.log_pdf_2.evaluateS1(param_2)
+
+        score, dscore = log_pdf.evaluateS1(param)
+        self.assertEqual(score, score_1 + score_2)
+
+        self.assertEqual(len(dscore), 3)
+        self.assertEqual(dscore[0], dscore_1[0])
+        self.assertEqual(dscore[1], dscore_2[0])
+        self.assertEqual(dscore[2], dscore_1[1] + dscore_2[1])
+
+    def test_evaluateS1_pooled(self):
+        log_pdfs = [self.log_pdf_1, self.log_pdf_2]
+        pooled = [True, True]
+        log_pdf = pkpd.PooledLogPDF(log_pdfs, pooled)
+
+        param_1 = [1, 0.2]
+        param_2 = [1, 0.2]
+        param = [1, 0.2]
+
+        score_1, dscore_1 = self.log_pdf_1.evaluateS1(param_1)
+        score_2, dscore_2 = self.log_pdf_2.evaluateS1(param_2)
+
+        score, dscore = log_pdf.evaluateS1(param)
+        self.assertEqual(score, score_1 + score_2)
+
+        self.assertEqual(len(dscore), 2)
+        self.assertEqual(dscore[0], dscore_1[0] + dscore_2[0])
+        self.assertEqual(dscore[1], dscore_1[1] + dscore_2[1])
+
+
 if __name__ == '__main__':
     unittest.main()

pip install -e .
parse_log_pytest
pytest
pytest
apt-get update apt-get install -y libsundials-dev
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
anyio==3.7.1
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
attrs @ file:///croot/attrs_1668696182826/work
backcall==0.2.0
beautifulsoup4==4.13.3
bleach==6.0.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffi==1.15.1
cma==4.0.0
comm==0.1.4
configparser==5.3.0
cycler==0.11.0
debugpy==1.7.0
decorator==5.1.1
defusedxml==0.7.1
entrypoints==0.4
exceptiongroup==1.2.2
fastjsonschema==2.21.1
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
fonttools==4.38.0
idna==3.10
importlib-metadata @ file:///tmp/build/80754af9/importlib-metadata_1648562407465/work
importlib-resources==5.12.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
ipykernel==6.16.2
ipython==7.34.0
ipython-genutils==0.2.0
ipywidgets==8.1.5
jedi==0.19.2
Jinja2==3.1.6
jsonschema==4.17.3
jupyter==1.0.0
jupyter-console==6.6.3
jupyter-server==1.24.0
jupyter_client==7.4.9
jupyter_core==4.12.0
jupyterlab-pygments==0.2.2
jupyterlab_widgets==3.0.13
kiwisolver==1.4.5
lxml==5.3.1
MarkupSafe==2.1.5
matplotlib==3.5.3
matplotlib-inline==0.1.6
mistune==3.0.2
myokit==1.37.3
nbclassic==1.2.0
nbclient==0.7.4
nbconvert==7.6.0
nbformat==5.8.0
nest-asyncio==1.6.0
notebook==6.5.7
notebook_shim==0.2.4
numpy==1.21.6
packaging @ file:///croot/packaging_1671697413597/work
pandas==1.3.5
pandocfilters==1.5.1
parso==0.8.4
pexpect==4.9.0
pickleshare==0.7.5
Pillow==9.5.0
pints==0.5.0
pkgutil_resolve_name==1.3.10
-e git+https://github.com/DavAug/ErlotinibGefitinib.git@407f42f622094cb7b2e43e9935ad71168f9098ca#egg=pkpd
plotly==4.8.1
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
prometheus-client==0.17.1
prompt_toolkit==3.0.48
psutil==7.0.0
ptyprocess==0.7.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pycparser==2.21
Pygments==2.17.2
pyparsing==3.1.4
pyrsistent==0.19.3
pytest==7.1.2
python-dateutil==2.9.0.post0
pytz==2025.2
pyzmq==26.2.1
qtconsole==5.4.4
QtPy==2.4.3
retrying==1.3.4
scipy==1.7.3
Send2Trash==1.8.3
six==1.17.0
sniffio==1.3.1
soupsieve==2.4.1
tabulate==0.9.0
terminado==0.17.1
threadpoolctl==3.1.0
tinycss2==1.2.1
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
tornado==6.2
tqdm==4.46.1
traitlets==5.9.0
typing_extensions @ file:///croot/typing_extensions_1669924550328/work
wcwidth==0.2.13
webencodings==0.5.1
websocket-client==1.6.1
widgetsnbextension==4.0.13
zipp @ file:///croot/zipp_1672387121353/work

name: ErlotinibGefitinib
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=22.1.0=py37h06a4308_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - flit-core=3.6.0=pyhd3eb1b0_0
  - importlib-metadata=4.11.3=py37h06a4308_0
  - importlib_metadata=4.11.3=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=22.0=py37h06a4308_0
  - pip=22.3.1=py37h06a4308_0
  - pluggy=1.0.0=py37h06a4308_1
  - py=1.11.0=pyhd3eb1b0_0
  - pytest=7.1.2=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py37h06a4308_0
  - typing_extensions=4.4.0=py37h06a4308_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.11.0=py37h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - anyio==3.7.1
      - argon2-cffi==23.1.0
      - argon2-cffi-bindings==21.2.0
      - backcall==0.2.0
      - beautifulsoup4==4.13.3
      - bleach==6.0.0
      - cffi==1.15.1
      - cma==4.0.0
      - comm==0.1.4
      - configparser==5.3.0
      - cycler==0.11.0
      - debugpy==1.7.0
      - decorator==5.1.1
      - defusedxml==0.7.1
      - entrypoints==0.4
      - exceptiongroup==1.2.2
      - fastjsonschema==2.21.1
      - fonttools==4.38.0
      - idna==3.10
      - importlib-resources==5.12.0
      - ipykernel==6.16.2
      - ipython==7.34.0
      - ipython-genutils==0.2.0
      - ipywidgets==8.1.5
      - jedi==0.19.2
      - jinja2==3.1.6
      - jsonschema==4.17.3
      - jupyter==1.0.0
      - jupyter-client==7.4.9
      - jupyter-console==6.6.3
      - jupyter-core==4.12.0
      - jupyter-server==1.24.0
      - jupyterlab-pygments==0.2.2
      - jupyterlab-widgets==3.0.13
      - kiwisolver==1.4.5
      - lxml==5.3.1
      - markupsafe==2.1.5
      - matplotlib==3.5.3
      - matplotlib-inline==0.1.6
      - mistune==3.0.2
      - myokit==1.37.3
      - nbclassic==1.2.0
      - nbclient==0.7.4
      - nbconvert==7.6.0
      - nbformat==5.8.0
      - nest-asyncio==1.6.0
      - notebook==6.5.7
      - notebook-shim==0.2.4
      - numpy==1.21.6
      - pandas==1.3.5
      - pandocfilters==1.5.1
      - parso==0.8.4
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pillow==9.5.0
      - pints==0.5.0
      - pkgutil-resolve-name==1.3.10
      - plotly==4.8.1
      - prometheus-client==0.17.1
      - prompt-toolkit==3.0.48
      - psutil==7.0.0
      - ptyprocess==0.7.0
      - pycparser==2.21
      - pygments==2.17.2
      - pyparsing==3.1.4
      - pyrsistent==0.19.3
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyzmq==26.2.1
      - qtconsole==5.4.4
      - qtpy==2.4.3
      - retrying==1.3.4
      - scipy==1.7.3
      - send2trash==1.8.3
      - six==1.17.0
      - sniffio==1.3.1
      - soupsieve==2.4.1
      - tabulate==0.9.0
      - terminado==0.17.1
      - threadpoolctl==3.1.0
      - tinycss2==1.2.1
      - tornado==6.2
      - tqdm==4.46.1
      - traitlets==5.9.0
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - websocket-client==1.6.1
      - widgetsnbextension==4.0.13
prefix: /opt/conda/envs/ErlotinibGefitinib

pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_bad_log_pdfs_objects pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_bad_log_pdfs_parameters pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_bad_number_log_pdfs pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_bad_pooled_content pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_bad_pooled_length pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_call_partially_pooled pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_call_pooled pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_call_unpooled pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_evaluateS1_partially_pooled pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_evaluateS1_pooled pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_evaluateS1_unpooled pkpd/tests/test_likelihoods.py::TestPooledLogPDF::test_n_parameters
pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_gaussian_log_likelihood_agrees_multi pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_gaussian_log_likelihood_agrees_single pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_list pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_multiplicative_gaussian_log_likelihood_agrees_multi pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_multiplicative_gaussian_log_likelihood_agrees_single pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_one_dim_array pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_two_dim_array_multi pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_call_two_dim_array_single pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_finite_difference_multi pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_finite_difference_single pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_gaussian_log_likelihood_agrees_multi pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_gaussian_log_likelihood_agrees_single pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_list pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_one_dim_array pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_two_dim_array_multi pkpd/tests/test_likelihoods.py::TestConstantAndMultiplicativeGaussianLogLikelihood::test_evaluateS1_two_dim_array_single pkpd/tests/test_likelihoods.py::TestFixedEtaLogLikelihoodWrapper::test_bad_likelihood pkpd/tests/test_likelihoods.py::TestFixedEtaLogLikelihoodWrapper::test_bad_n_output pkpd/tests/test_likelihoods.py::TestFixedEtaLogLikelihoodWrapper::test_call_constant_and_multiplicative_log_likelihood pkpd/tests/test_likelihoods.py::TestFixedEtaLogLikelihoodWrapper::test_call_multiplicative_log_likelihood pkpd/tests/test_likelihoods.py::TestFixedEtaLogLikelihoodWrapper::test_evaluateS1 pkpd/tests/test_likelihoods.py::TestFixedEtaLogLikelihoodWrapper::test_n_parameters
pkpd/__init__.py pkpd/_likelihoods.py
pkpd/__init__.py pkpd/_likelihoods.py