Example #1
0
def test_choose_param_init(pheno_path, testdata):
    model = Model(pheno_path)
    params = (model.parameters['OMEGA(1,1)'], model.parameters['OMEGA(2,2)'])
    rvs = RandomVariables(model.random_variables.etas)
    init = _choose_param_init(model, rvs, params)

    assert init == 0.0118179

    model = Model(pheno_path)
    model.source.path = testdata  # Path where there is no .ext-file
    init = _choose_param_init(model, rvs, params)

    assert init == 0.0031045

    model = Model(pheno_path)

    omega1 = S('OMEGA(3,3)')
    x = stats.Normal('ETA(3)', 0, sympy.sqrt(omega1))
    x.variability_level = VariabilityLevel.IIV
    rvs.add(x)

    ie = model.modelfit_results.individual_estimates
    ie['ETA(3)'] = ie['ETA(1)']
    model.modelfit_results = ModelfitResults(individual_estimates=ie)

    init = _choose_param_init(model, rvs, params)

    assert init == 0.0118179
Example #2
0
def test_extract_from_block():
    etas = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0],
                               [[3, 0.25], [0.25, 1]])
    for rv in etas:
        rv.variability_level = VariabilityLevel.IIV
    rvs = RandomVariables(etas)
    eta3 = stats.Normal('ETA(3)', 0.5, 2)
    eta3.variability_level = VariabilityLevel.IIV
    rvs.add(eta3)

    dists = rvs.distributions()
    assert len(dists) == 2

    rvs.extract_from_block(etas[0])
    dists = rvs.distributions()
    assert len(dists) == 3
    assert rvs[0].name == 'ETA(1)'
    assert rvs[2].name == 'ETA(3)'
Example #3
0
def create_rv_block(model, list_of_rvs=None):
    """
    Creates a full or partial block structure of etas. The etas must be IIVs and cannot
    be fixed. Initial estimates for covariance between the etas is dependent on whether
    the model has results from a previous results. In that case, the correlation will
    be calculated from individual estimates, otherwise correlation will be set to 10%.

    Parameters
    ----------
    model : Model
        Pharmpy model to create block effect on.
    list_of_rvs : list
        List of etas to create a block structure from. If None, all etas that are IIVs and
        non-fixed will be used (full block). None is default.
    """
    rvs_full = model.random_variables
    rvs_block = _get_rvs(model, list_of_rvs)

    if list_of_rvs is not None:
        for rv in rvs_block:
            if isinstance(rv.pspace.distribution, MultivariateNormalDistribution):
                if rvs_full.get_rvs_from_same_dist(rv):
                    rv_extracted = rvs_full.extract_from_block(rv)
                    rvs_block.discard(rv)
                    rvs_block.add(rv_extracted)

    pset = _merge_rvs(model, rvs_block)

    rvs_new = RandomVariables()
    are_consecutive = rvs_full.are_consecutive(rvs_block)

    for rv in rvs_full:
        if rv.name not in [rv.name for rv in rvs_block.etas]:
            rvs_new.add(rv)
        elif are_consecutive:
            rvs_new.add(rvs_block[rv.name])

    if not are_consecutive:
        {rvs_new.add(rv) for rv in rvs_block}  # Add new block last

    model.random_variables = rvs_new
    model.parameters = pset

    return model
Example #4
0
    def random_variables(self, start_omega, previous_cov=None):
        """Get a RandomVariableSet for this omega record

           start_omega - the first omega in this record
           previous_sigma - the matrix of the previous omega block
        """
        next_cov = None        # The cov matrix if a block
        block = self.root.find('block')
        bare_block = self.root.find('bare_block')
        zero_fix = []
        if not (block or bare_block):
            rvs = RandomVariables()
            i = start_omega
            numetas = len(self.root.all('diag_item'))
            for node in self.root.all('diag_item'):
                init = node.init.NUMERIC
                fixed = bool(node.find('FIX'))
                name = self._rv_name(i)
                if not (init == 0 and fixed):       # 0 FIX are not RVs
                    eta = sympy.stats.Normal(name, 0, sympy.sqrt(
                        sympy.Symbol(f'{self.name}({i},{i})')))
                    rvs.add(eta)
                else:
                    zero_fix.append(name)
                i += 1
        else:
            if bare_block:
                numetas = previous_cov.rows
            else:
                numetas = self.root.block.size.INT
            same = bool(self.root.find('same'))
            params, _, _ = self.parameters(start_omega, previous_cov.rows if
                                           hasattr(previous_cov, 'rows') else None)
            all_zero_fix = True
            for param in params:
                if not (param.init == 0 and param.fix):
                    all_zero_fix = False
            if all_zero_fix and len(params) > 0 or (previous_cov == 'ZERO' and same):
                names = [self._rv_name(i) for i in range(start_omega, start_omega + numetas)]
                return RandomVariables(), start_omega + numetas, 'ZERO', names
            if numetas > 1:
                names = [self._rv_name(i) for i in range(start_omega, start_omega + numetas)]
                means = [0] * numetas
                if same:
                    rvs = JointNormalSeparate(names, means, previous_cov)
                    next_cov = previous_cov
                else:
                    cov = sympy.zeros(numetas)
                    for row in range(numetas):
                        for col in range(row + 1):
                            cov[row, col] = sympy.Symbol(
                                f'{self.name}({start_omega + row},{start_omega + col})')
                            if row != col:
                                cov[col, row] = cov[row, col]
                    next_cov = cov
                    rvs = JointNormalSeparate(names, means, cov)
            else:
                rvs = RandomVariables()
                name = self._rv_name(start_omega)
                if same:
                    symbol = previous_cov
                else:
                    symbol = sympy.Symbol(f'{self.name}({start_omega},{start_omega})')
                eta = sympy.stats.Normal(name, 0, sympy.sqrt(symbol))
                next_cov = symbol
                rvs.add(eta)

        if self.name == 'OMEGA':
            level = VariabilityLevel.IIV
        else:
            level = VariabilityLevel.RUV
        for rv in rvs:
            rv.variability_level = level

        return rvs, start_omega + numetas, next_cov, zero_fix
Example #5
0
    def random_variables(self, start_omega, previous_cov=None):
        """Get a RandomVariableSet for this omega record

        start_omega - the first omega in this record
        previous_cov - the matrix of the previous omega block
        """
        same = bool(self.root.find('same'))
        if not hasattr(self, 'name_map') and not same:
            if isinstance(previous_cov, sympy.Symbol):
                prev_size = 1
            elif previous_cov is not None:
                prev_size = len(previous_cov)
            else:
                prev_size = None
            self.parameters(start_omega, prev_size)
        if hasattr(self, 'name_map'):
            rev_map = {value: key for key, value in self.name_map.items()}
        next_cov = None  # The cov matrix if a block
        block = self.root.find('block')
        bare_block = self.root.find('bare_block')
        zero_fix = []
        etas = []
        if not (block or bare_block):
            rvs = RandomVariables()
            i = start_omega
            numetas = len(self.root.all('diag_item'))
            for node in self.root.all('diag_item'):
                init = node.init.NUMERIC
                fixed = bool(node.find('FIX'))
                name = self._rv_name(i)
                if not (init == 0 and fixed):  # 0 FIX are not RVs
                    eta = sympy.stats.Normal(
                        name, 0, sympy.sqrt(symbol(rev_map[(i, i)])))
                    rvs.add(eta)
                    etas.append(eta.name)
                else:
                    zero_fix.append(name)
                    etas.append(name)
                i += 1
        else:
            if bare_block:
                numetas = previous_cov.rows
            else:
                numetas = self.root.block.size.INT
            params, _, _ = self.parameters(
                start_omega,
                previous_cov.rows if hasattr(previous_cov, 'rows') else None)
            all_zero_fix = True
            for param in params:
                if not (param.init == 0 and param.fix):
                    all_zero_fix = False
            if all_zero_fix and len(params) > 0 or (previous_cov == 'ZERO'
                                                    and same):
                names = [
                    self._rv_name(i)
                    for i in range(start_omega, start_omega + numetas)
                ]
                self.eta_map = {
                    eta: start_omega + i
                    for i, eta in enumerate(names)
                }
                return RandomVariables(), start_omega + numetas, 'ZERO', names
            if numetas > 1:
                names = [
                    self._rv_name(i)
                    for i in range(start_omega, start_omega + numetas)
                ]
                means = [0] * numetas
                if same:
                    rvs = JointNormalSeparate(names, means, previous_cov)
                    etas = [rv.name for rv in rvs]
                    next_cov = previous_cov
                else:
                    cov = sympy.zeros(numetas)
                    for row in range(numetas):
                        for col in range(row + 1):
                            cov[row,
                                col] = symbol(rev_map[(start_omega + row,
                                                       start_omega + col)])
                            if row != col:
                                cov[col, row] = cov[row, col]
                    next_cov = cov
                    rvs = JointNormalSeparate(names, means, cov)
                    etas = [rv.name for rv in rvs]
            else:
                rvs = RandomVariables()
                name = self._rv_name(start_omega)
                if same:
                    sym = previous_cov
                else:
                    sym = symbol(rev_map[(start_omega, start_omega)])
                eta = sympy.stats.Normal(name, 0, sympy.sqrt(sym))
                next_cov = sym
                rvs.add(eta)
                etas.append(eta.name)

        if self.name == 'OMEGA':
            if same:
                level = VariabilityLevel.IOV
            else:
                level = VariabilityLevel.IIV
        else:
            level = VariabilityLevel.RUV
        for rv in rvs:
            rv.variability_level = level
        self.eta_map = {eta: start_omega + i for i, eta in enumerate(etas)}
        return rvs, start_omega + numetas, next_cov, zero_fix