Beispiel #1
0
 def statements(self, new):
     try:
         old = self._statements
     except AttributeError:
         old = self.statements
     if new == old:
         return
     old_index = 0
     node_index = 0
     kept = []
     new_nodes = []
     defined_symbols = set()  # Set of all defined symbols updated so far
     for op, s in diff(old, new):
         while (node_index < len(self.root.children)
                and old_index < len(self.nodes)
                and self.root.children[node_index]
                is not self.nodes[old_index]):
             node = self.root.children[node_index]
             kept.append(node)
             node_index += 1
         if op == '+':
             if isinstance(s.expression, Piecewise):
                 statement_str = self._translate_sympy_piecewise(
                     s, defined_symbols)
             elif re.search('sign', str(s.expression)):
                 statement_str = self._translate_sympy_sign(s)
             else:
                 statement_str = s.print_custom(self.rvs, self.trans)
             node_tree = CodeRecordParser(statement_str).root
             for node in node_tree.all('statement'):
                 if node_index == 0:
                     node.children.insert(0, AttrToken('LF', '\n'))
                 if (not node.all('LF') and node_index != 0
                         or len(self.root.children) > 0
                         and self.root.children[0].rule != 'empty_line'):
                     node.children.append(AttrToken('LF', '\n'))
                 new_nodes.append(node)
                 kept.append(node)
             defined_symbols.add(s.symbol)
         elif op == '-':
             node_index += 1
             old_index += 1
         else:
             kept.append(self.root.children[node_index])
             new_nodes.append(self.root.children[node_index])
             node_index += 1
             old_index += 1
             defined_symbols.add(s.symbol)
     if node_index < len(self.root.children):  # Remaining non-statements
         kept.extend(self.root.children[node_index:])
     self.root.children = kept
     self.nodes = new_nodes
     self._statements = new.copy()
Beispiel #2
0
 def statements(self, new):
     try:
         old = self._statements
     except AttributeError:
         old = self.statements
     if new == old:
         return
     old_index = 0
     node_index = 0
     kept = []
     new_nodes = []
     for op, s in diff(old, new):
         while (node_index < len(self.root.children)
                and old_index < len(self.nodes)
                and self.root.children[node_index]
                is not self.nodes[old_index]):
             node = self.root.children[node_index]
             kept.append(node)
             node_index += 1
         if op == '+':
             if isinstance(s.expression, Piecewise):
                 statement_str = self._translate_sympy_piecewise(s)
             elif re.search('sign', str(s.expression)):
                 statement_str = self._translate_sympy_sign(s)
             else:
                 statement_str = f'\n{repr(s).replace(":", "")}'
             node_tree = CodeRecordParser(statement_str).root
             node = node_tree.all('statement')[0]
             if node_index == 0:
                 node.children.insert(0, AttrToken('LF', '\n'))
             if (node_index != 0 or len(self.root.children) > 0
                     and self.root.children[0].rule != 'empty_line'):
                 node.children.append(AttrToken('LF', '\n'))
             new_nodes.append(node)
             kept.append(node)
         elif op == '-':
             node_index += 1
             old_index += 1
         else:
             kept.append(self.root.children[node_index])
             new_nodes.append(self.root.children[node_index])
             node_index += 1
             old_index += 1
     if node_index < len(self.root.children):  # Remaining non-statements
         kept.extend(self.root.children[node_index:])
     self.root.children = kept
     self.nodes = new_nodes
     self._statements = new.copy()
Beispiel #3
0
    def update(self, parameters, first_theta):
        """From a ParameterSet update the THETAs in this record

        Currently only updating initial estimates
        """
        i = first_theta
        for theta in self.root.all('theta'):
            name = f'THETA({i})'
            param = parameters[name]
            new_init = param.init
            if float(str(theta.init)) != new_init:
                theta.init.tokens[0].value = str(new_init)
            fix = bool(theta.find('FIX'))
            if fix != param.fix:
                if param.fix:
                    space = AttrToken('WS', ' ')
                    fix_token = AttrToken('FIX', 'FIX')
                    theta.children.extend([space, fix_token])
                else:
                    remove_token_and_space(theta, 'FIX')

            n = self._multiple(theta)
            i += n
Beispiel #4
0
    def update(self, parameters, first_omega, previous_size):
        """From a ParameterSet update the OMEGAs in this record
           returns the next omega number
        """
        block = self.root.find('block')
        bare_block = self.root.find('bare_block')
        if not (block or bare_block):
            size = 1
            i = first_omega
            new_nodes = []
            for node in self.root.children:
                if node.rule != 'diag_item':
                    new_nodes.append(node)
                else:
                    sd = bool(node.find('SD'))
                    fix = bool(node.find('FIX'))
                    n = node.n.INT if node.find('n') else 1
                    new_inits = []
                    new_fix = []
                    for j in range(i, i + n):
                        name = f'{self.name}({j},{j})'
                        if not sd:
                            value = float(parameters[name].init)
                        else:
                            value = parameters[name].init ** 0.5
                        new_inits.append(value)
                        new_fix.append(parameters[name].fix)
                    if n == 1 or (new_inits.count(new_inits[0]) == len(new_inits) and
                                  new_fix.count(new_fix[0]) == len(new_fix)):  # All equal?
                        if float(str(node.init)) != new_inits[0]:
                            node.init.tokens[0].value = str(new_inits[0])
                        if new_fix[0] != fix:
                            if new_fix[0]:
                                insert_before_or_at_end(node, 'RPAR', [AttrToken('WS', ' '),
                                                                       AttrToken('FIX', 'FIX')])
                            else:
                                remove_token_and_space(node, 'FIX')
                        new_nodes.append(node)
                    else:
                        # Need to split xn
                        new_children = []
                        for child in node.children:
                            if child.rule != 'n':
                                new_children.append(child)
                        node.children = new_children
                        for j, init in enumerate(new_inits):
                            new_node = AttrTree.transform(node)
                            if float(str(new_node.init)) != init:
                                new_node.init.tokens[0].value = str(init)
                            if new_fix[j] != fix:
                                insert_before_or_at_end(node, 'RPAR', [AttrToken('WS', ' '),
                                                                       AttrToken('FIX', 'FIX')])
                            else:
                                remove_token_and_space(node, 'FIX')
                            new_nodes.append(new_node)
                            if j != len(new_inits) - 1:     # Not the last
                                new_nodes.append(AttrTree.create('ws', {'WS': ' '}))
                    i += n
            self.root.children = new_nodes
            next_omega = i
        else:
            same = bool(self.root.find('same'))
            if same:
                return first_omega + previous_size, previous_size
            size = self.root.block.size.INT
            fix, sd, corr, cholesky = self._block_flags()
            row = first_omega
            col = first_omega
            inits = []
            new_fix = []
            for row in range(first_omega, first_omega + size):
                for col in range(first_omega, row + 1):
                    name = f'{self.name}({row},{col})'
                    inits.append(parameters[name].init)
                    new_fix.append(parameters[name].fix)
            if len(set(new_fix)) != 1:      # Not all true or all false
                raise ValueError('Cannot only fix some parameters in block')

            A = pharmpy.math.flattened_to_symmetric(inits)

            if corr:
                for i in range(size):
                    for j in range(size):
                        if i != j:
                            A[i, j] = A[i, j] / (math.sqrt(A[i, i]) * math.sqrt(A[j, j]))
            if sd:
                np.fill_diagonal(A, A.diagonal()**0.5)

            if cholesky:
                A = np.linalg.cholesky(A)

            inds = np.tril_indices_from(A)
            array = list(A[inds])
            i = 0
            new_nodes = []
            for node in self.root.children:
                if node.rule != 'omega':
                    new_nodes.append(node)
                else:
                    n = node.n.INT if node.find('n') else 1
                    if array[i:i+n].count(array[i]) == n:  # All equal?
                        if float(str(node.init)) != array[i]:
                            node.init.tokens[0].value = str(array[i])
                        new_nodes.append(node)
                    else:
                        # Need to split xn
                        new_children = []
                        for child in node.children:
                            if child.rule not in ['n', 'LPAR', 'RPAR']:
                                new_children.append(child)
                        node.children = new_children
                        for j, init in enumerate(array[i:i+n]):
                            new_node = AttrTree.transform(node)
                            if float(str(new_node.init)) != init:
                                new_node.init.tokens[0].value = str(init)
                            new_nodes.append(new_node)
                            if j != n - 1:     # Not the last
                                new_nodes.append(AttrTree.create('ws', {'WS': ' '}))
                    i += n
            self.root.children = new_nodes
            if new_fix[0] != fix:
                if new_fix[0]:
                    insert_after(self.root, 'block', [AttrToken('WS', ' '),
                                                      AttrToken('FIX', 'FIX')])
                else:
                    remove_token_and_space(self.root, 'FIX', recursive=True)
            next_omega = first_omega + size
        return next_omega, size