예제 #1
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
예제 #2
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