예제 #1
0
def test_pset_nonfixed_inits():
    p1 = Parameter('Y', 9)
    p2 = Parameter('X', 3)
    p3 = Parameter('Z', 1)
    pset = Parameters([p1, p2, p3])
    assert pset.nonfixed_inits == {'Y': 9, 'X': 3, 'Z': 1}
    pset['X'].fix = True
    assert pset.nonfixed_inits == {'Y': 9, 'Z': 1}
예제 #2
0
def test_pset_discard():
    p1 = Parameter('Y', 9)
    p2 = Parameter('X', 3)
    p3 = Parameter('Z', 1)
    pset1 = Parameters([p1, p2, p3])
    del pset1[p2]
    assert len(pset1) == 2
    del pset1['Y']
    assert len(pset1) == 1
예제 #3
0
def test_pset_inits():
    p1 = Parameter('Y', 9)
    p2 = Parameter('X', 3)
    p3 = Parameter('Z', 1)
    pset = Parameters([p1, p2, p3])
    pset.inits = {'X': 28}
    assert len(pset) == 3
    assert pset['X'] == Parameter('X', 28)
    assert pset['Y'] == Parameter('Y', 9)
    assert pset['Z'] == Parameter('Z', 1)

    with pytest.raises(KeyError):
        pset.inits = {'CL': 0}

    pset.inits = {'X': 0, 'Y': 2, 'Z': 5}
    assert len(pset) == 3
    assert pset['X'] == Parameter('X', 0)
    assert pset['Y'] == Parameter('Y', 2)
    assert pset['Z'] == Parameter('Z', 5)
예제 #4
0
def test_pset_repr():
    p1 = Parameter('Y', 9, fix=False)
    pset = Parameters([p1])
    assert type(repr(pset)) == str
    assert type(pset._repr_html_()) == str
    pset = Parameters()
    assert type(repr(pset)) == str
    assert type(pset._repr_html_()) == str
예제 #5
0
def test_pset_add():
    p1 = Parameter('Y', 9)
    p2 = Parameter('X', 3)
    p3 = Parameter('Z', 1)
    pset1 = Parameters([p1, p2])
    pset1.append(p3)
    assert len(pset1) == 3

    with pytest.raises(ValueError):
        pset1.append(23)
예제 #6
0
def test_pset_setitem():
    p1 = Parameter('P1', 1)
    p2 = Parameter('P2', 2)
    p3 = Parameter('P3', 3)
    ps = Parameters([p1, p2, p3])
    p4 = Parameter('P4', 4)
    ps[p1] = p4
    assert len(ps) == 3
    assert ps[0].name == 'P4'

    with pytest.raises(ValueError):
        ps[0] = 23

    p5 = Parameter('P4', 0)
    with pytest.raises(ValueError):
        ps[1] = p5
예제 #7
0
 def _read_parameters(self):
     next_theta = 1
     params = Parameters()
     for theta_record in self.control_stream.get_records('THETA'):
         thetas = theta_record.parameters(next_theta,
                                          seen_labels=set(params.names))
         params.extend(thetas)
         next_theta += len(thetas)
     next_omega = 1
     previous_size = None
     for omega_record in self.control_stream.get_records('OMEGA'):
         omegas, next_omega, previous_size = omega_record.parameters(
             next_omega, previous_size, seen_labels=set(params.names))
         params.extend(omegas)
     next_sigma = 1
     previous_size = None
     for sigma_record in self.control_stream.get_records('SIGMA'):
         sigmas, next_sigma, previous_size = sigma_record.parameters(
             next_sigma, previous_size, seen_labels=set(params.names))
         params.extend(sigmas)
     self._parameters = params
     self._old_parameters = params.copy()
예제 #8
0
def test_insert():
    p1 = Parameter('Y', 9)
    p2 = Parameter('X', 3, lower=1, upper=24)
    p3 = Parameter('Z', 1, lower=0, upper=2)
    pset1 = Parameters([p1, p2])
    pset1.insert(0, p3)
    assert pset1.names == ['Z', 'Y', 'X']

    p4 = Parameter('Y', 0)
    with pytest.raises(ValueError):
        pset1.insert(1, p4)
예제 #9
0
    def parameters(self, start_omega, previous_size, seen_labels=None):
        """Get a Parameters for this omega record"""
        row = start_omega
        block = self.root.find('block')
        bare_block = self.root.find('bare_block')
        same = bool(self.root.find('same'))
        parameters = Parameters()
        coords = []

        try:
            self.comment_map
        except AttributeError:
            self.comment_map = dict()

        if seen_labels is None:
            seen_labels = set()
        if not (block or bare_block):
            for node in self.root.all('diag_item'):
                init = node.init.NUMERIC
                fixed = bool(node.find('FIX'))
                sd = bool(node.find('SD'))
                var = bool(node.find('VAR'))
                n = node.n.INT if node.find('n') else 1
                if sd and var:
                    raise ModelSyntaxError(
                        f'Initial estimate for {self.name.upper()} cannot be both'
                        f' on SD and VAR scale\n{self.root}'
                    )
                if init == 0 and not fixed:
                    raise ModelSyntaxError(
                        f'If initial estimate for {self.name.upper()} is 0 it'
                        f' must be set to FIX'
                    )
                if sd:
                    init = init ** 2
                for _ in range(n):
                    name = self._find_label(node, seen_labels)
                    comment = self._get_name(node)
                    if not name:
                        name = f'{self.name}({row},{row})'
                    if comment:
                        self.comment_map[name] = comment
                    seen_labels.add(name)
                    coords.append((row, row))
                    param = Parameter(name, init, lower=0, fix=fixed)
                    parameters.append(param)
                    row += 1
            size = 1
            next_omega = row
        else:
            inits = []
            if bare_block:
                size = previous_size
            else:
                size = self.root.block.size.INT
            fix, sd, corr, cholesky = self._block_flags()
            labels = []
            for node in self.root.all('omega'):
                init = node.init.NUMERIC
                n = node.n.INT if node.find('n') else 1
                inits += [init] * n
                name = self._find_label(node, seen_labels)
                if name is not None:
                    seen_labels.add(name)
                labels.append(name)
                if n > 1:
                    labels.extend([None] * (n - 1))
            if not same:
                if size != pharmpy.math.triangular_root(len(inits)):
                    raise ModelSyntaxError('Wrong number of inits in BLOCK')
                if not cholesky:
                    A = pharmpy.math.flattened_to_symmetric(inits)
                    if corr:
                        for i in range(size):
                            for j in range(size):
                                if i != j:
                                    if sd:
                                        A[i, j] = A[i, i] * A[j, j] * A[i, j]
                                    else:
                                        A[i, j] = math.sqrt(A[i, i]) * math.sqrt(A[j, j]) * A[i, j]
                    if sd:
                        np.fill_diagonal(A, A.diagonal() ** 2)
                else:
                    L = np.zeros((size, size))
                    inds = np.tril_indices_from(L)
                    L[inds] = inits
                    A = L @ L.T
                label_index = 0
                for i in range(size):
                    for j in range(0, i + 1):
                        name = labels[label_index]
                        if name is None:
                            name = f'{self.name}({i + start_omega},{j + start_omega})'
                        coords.append((i + start_omega, j + start_omega))
                        init = A[i, j]
                        lower = None if i != j else 0
                        param = Parameter(name, init, lower=lower, fix=fix)
                        parameters.append(param)
                        label_index += 1
            next_omega = start_omega + size
        try:
            self.name_map
        except AttributeError:
            self.name_map = {name: c for i, (name, c) in enumerate(zip(parameters.names, coords))}
        return parameters, next_omega, size
예제 #10
0
    def parameters(self, first_theta, seen_labels=None):
        """Get a parameter set for this theta record.
        first_theta is the number of the first theta in this record
        """
        if seen_labels is None:
            seen_labels = set()
        pset = Parameters()
        current_theta = first_theta
        for theta in self.root.all('theta'):
            init = theta.init.tokens[0].eval
            fix = bool(theta.find('FIX'))
            if theta.find('low'):
                if theta.low.find('NEG_INF'):
                    lower = min_lower_bound
                else:
                    lower = theta.low.tokens[0].eval
            else:
                lower = min_lower_bound
            if theta.find('up'):
                if theta.up.find('POS_INF'):
                    upper = max_upper_bound
                else:
                    upper = theta.up.tokens[0].eval
            else:
                upper = max_upper_bound
            multiple = theta.find('n')
            if multiple:
                n = multiple.INT
            else:
                n = 1
            for i in range(0, n):
                name = None
                import pharmpy.plugins.nonmem as nonmem

                if 'comment' in nonmem.conf.parameter_names:
                    # needed to avoid circular import with Python 3.6
                    found = False
                    for subnode in self.root.tree_walk():
                        if id(subnode) == id(theta):
                            if found:
                                break
                            else:
                                found = True
                                continue
                        if found and subnode.rule == 'NEWLINE':
                            m = re.search(r';\s*([a-zA-Z_]\w*)', str(subnode))
                            if m:
                                name = m.group(1)
                                break
                    if name in seen_labels:
                        warnings.warn(
                            f'The parameter name {name} is duplicated. Falling back to basic '
                            f'NONMEM names.')
                        name = None

                if not name:
                    name = f'THETA({current_theta})'
                seen_labels.add(name)
                new_par = Parameter(name, init, lower, upper, fix)
                current_theta += 1
                pset.append(new_par)

        if not self.name_map:
            self.name_map = {
                name: first_theta + i
                for i, name in enumerate(pset.names)
            }
        return pset
예제 #11
0
def test_simplify():
    x = sympy.Symbol('x')
    y = sympy.Symbol('y')

    p1 = Parameter('x', 3)
    p2 = Parameter('y', 9, fix=True)
    pset = Parameters([p1, p2])
    assert pset.simplify(x * y) == 9.0 * x

    p1 = Parameter('x', 3, lower=0.001)
    p2 = Parameter('y', 9)
    pset = Parameters([p1, p2])
    assert pset.simplify(abs(x)) == x

    p1 = Parameter('x', 3, lower=0)
    p2 = Parameter('y', 9)
    pset = Parameters([p1, p2])
    assert pset.simplify(sympy.Piecewise((2, sympy.Ge(x, 0)), (56, True))) == 2

    p1 = Parameter('x', -3, upper=-1)
    p2 = Parameter('y', 9)
    pset = Parameters([p1, p2])
    assert pset.simplify(abs(x)) == -x

    p1 = Parameter('x', -3, upper=0)
    p2 = Parameter('y', 9)
    pset = Parameters([p1, p2])
    assert pset.simplify(sympy.Piecewise((2, sympy.Le(x, 0)), (56, True))) == 2

    p1 = Parameter('x', 3)
    p2 = Parameter('y', 9)
    pset = Parameters([p1, p2])
    assert pset.simplify(x * y) == x * y
예제 #12
0
def test_pset_lower_upper():
    p1 = Parameter('X', 0, lower=-1, upper=1)
    p2 = Parameter('Y', 1, lower=0)
    pset = Parameters([p1, p2])
    assert pset.lower == {'X': -1, 'Y': 0}
    assert pset.upper == {'X': 1, 'Y': sympy.oo}