Beispiel #1
0
def solve_path2(s1, s2):
    """
    Input:
        s1 and s2: strs of ratelaws; variable is 'X'
        solve_for: 'X' or 'J'
        #idx_root: 0 or 1, since there can be two roots (if v1 - v2 == 0 
        #    is a quadratic equation)
    
    Output:
        A tuple of  (X string, J string)
    """
    if 'inf' in s1 and 'inf' in s2:
        raise ValueError
    elif 'inf' in s1:
        Xstr = str(sympy.solve(s1.replace('inf', '1'), 'X', simplify=True)[0])
        Jstr = exprmanip.simplify_expr(exprmanip.sub_for_var(s2, 'X', Xstr))
    elif 'inf' in s2:
        Xstr = str(sympy.solve(s2.replace('inf', '1'), 'X', simplify=True)[0])
        Jstr = exprmanip.simplify_expr(exprmanip.sub_for_var(s1, 'X', Xstr))
    else:
        eqn = '(%s) - (%s)' % (s1, s2)
        roots = sympy.solve(eqn, 'X', simplify=True)
        if len(roots) == 2:
            # choose the positive root (can be the 1st or the 2nd of the two)
            bools = ['+ sqrt' in str(sympy.expand(root)) for root in roots]
            idx = bools.index(True)
            Xstr = str(roots[idx])
        else:
            Xstr = str(roots[0])
        Jstr = exprmanip.simplify_expr(exprmanip.sub_for_var(s1, 'X', Xstr))
    """
    try:
        xsol = str(roots[1])
        varids = list(exprmanip.extract_vars(xsol))
        tests = [] 
        for i in range(10):
            subs = dict(zip(varids, np.random.lognormal(size=len(varids))))
            subs['sqrt'] = np.sqrt
            tests.append(eval(xsol, subs) > 0)
        if not all(tests):
            raise ValueError
    except (IndexError, ValueError):
        xsol = str(roots[0])
    """

    return Xstr, Jstr
    def test_sub_for_var(self):
        cases = [
            ('x', 'x', 'y', 'y'),
            ('x + 1', 'x', 'y', 'y + 1'),
            ('f(x)**2 - y + z', 'x', 'y*z/(x-2)', 'f(y*z/(x-2))**2 - y + z'),
            ('x**2', 'x', 'y+2', '(y+2)**2'),
            ('p[0]**x', 'x', 'y+2', 'p[0]**(y+2)'),
            ('g(x, y, f(z)) != y+2 and z == y', 'z', 'y',
             '(g(x, y, f(y)) != (y + 2)) and (y == y)'),
        ]

        for expr, out_var, in_expr, answer in cases:
            subbed = ExprManip.sub_for_var(expr, out_var, in_expr)
            assert eval(answer) == eval(subbed)
Beispiel #3
0
    def replace_varid(self, varid_old, varid_new, only_expr=False):
        """Change id of reaction, species, or parameter.
        
        :param only_expr: bool; if True, only replace varid in expressions 
            such as reaction ratelaws or assignment rules but not variable ids; 
            useful when varid_new == 'varid_old * r'
        """
        if only_expr:
            f = lambda varid: varid
        else:
            f = lambda varid: varid_new if varid == varid_old else varid

        netid_new = f(self.id)
        net_new = self.__class__(netid_new)

        for var in self.variables:
            var_new = copy.deepcopy(var)
            var_new.id = f(var.id)
            net_new.variables.set(var_new.id, var_new)

        for rxn in self.reactions:
            rxn_new = copy.deepcopy(rxn)
            rxn_new.id = f(rxn.id)
            rxn_new.stoichiometry = OD(
                zip(map(f, rxn.stoichiometry.keys()),
                    rxn.stoichiometry.values()))
            try:
                rxn_new.reactant_stoichiometry =\
                    OD(zip(map(f, rxn.reactant_stoichiometry.keys()),
                           rxn.reactant_stoichiometry.values()))
                rxn_new.product_stoichiometry =\
                    OD(zip(map(f, rxn.product_stoichiometry.keys()),
                           rxn.product_stoichiometry.values()))
            except AttributeError:  # some rxns have no reactant/product stoich
                pass

            rxn_new.parameters = set(map(f, rxn.parameters))
            rxn_new.kineticLaw = exprmanip.sub_for_var(rxn.kineticLaw,
                                                       varid_old, varid_new)
            net_new.reactions.set(rxn_new.id, rxn_new)

        for varid, rule in self.assignmentRules.items():
            net_new.assignmentRules.set(
                f(varid), exprmanip.sub_for_var(rule, varid_old, varid_new))

        for varid, rule in self.algebraicRules.items():
            net_new.algebraicRules.set(
                exprmanip.sub_for_var(varid, varid_old, varid_new),
                exprmanip.sub_for_var(rule, varid_old, varid_new))

        for varid, rule in self.rateRules.items():
            net_new.rateRules.set(
                f(varid), exprmanip.sub_for_var(rule, varid_old, varid_new))

        for eid, event in self.events.items():
            eid_new = f(eid)
            trigger_new = exprmanip.sub_for_var(event.trigger, varid_old,
                                                varid_new)
            assignments_new = OD(
                zip(map(f, event.event_assignments.keys()),
                    event.event_assignments.values()))
            net_new.add_event(eid_new, trigger_new, assignments_new)

        net_new.functionDefinitions = self.functionDefinitions.copy()
        for fid, f in net_new.functionDefinitions.items():
            fstr = 'lambda %s: %s' % (','.join(f.variables), f.math)
            net_new.namespace[fid] = eval(fstr, net_new.namespace)

        # _makeCrossReferences will take care of at least the following
        # attributes:
        # assignedVars, constantVars, optimizableVars, dynamicVars,
        # algebraicVars
        net_new._makeCrossReferences()
        return net_new