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}
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
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)
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
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)
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
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()
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)
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
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
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
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}