def get_h(self, keep1=True):
        """
        c = h(p)
        """
        hs = [poly.get_h(keep1=keep1) for poly in self]
        yids = butil.flatten([h_.yids for h_ in hs])
        coefstrs = butil.flatten([h_.frepr.tolist() for h_ in hs])
        senstrs = [[exprmanip.simplify_expr(exprmanip.diff_expr(coefstr, pid))
                    for pid in self.pids] for coefstr in coefstrs]
        
        hstr = str(coefstrs).replace("'", "")
        Dhstr = str(senstrs).replace("'", "") 
        
        subs0 = dict(butil.flatten([poly.convarvals.items() for poly in self], 
                                   depth=1))
        def f(p):
            subs = subs0.copy()
            subs.update(dict(zip(self.pids, p)))
            return np.array(eval(hstr, subs))
        
        def Df(p):
            subs = subs0.copy()
            subs.update(dict(zip(self.pids, p)))
            return np.array(eval(Dhstr, subs))

        h = predict.Predict(f=f, Df=Df, pids=self.pids, p0=self.p0, 
                            yids=yids, frepr=butil.Series(coefstrs, yids),
                            Dfrepr=butil.DF(senstrs, yids, self.pids))
        return h
 def __init__(self,
              data=None,
              index=None,
              columns=None,
              dtype='float',
              copy=False):
     """Make a *simple* or *composite* ensemble.
     
     Simple ensembles have ``pandas.Index`` as columns, while
     composite ensembles have ``pandas.MultiIndex`` as columns.
      
     Input:
         varids: {list-like, map-like}
     """
     if isinstance(columns, OD):
         columns = [[(vartype, varid) for varid in varids]
                    for vartype, varids in columns.items()]
         columns = butil.flatten(columns, depth=1)
         columns = pd.MultiIndex.from_tuples(columns)
     super(DF, self).__init__(data=data,
                              index=index,
                              columns=columns,
                              dtype='float',
                              copy=copy)
     self.index.name = 'step'
def list2predict2(l, pids, uids=None, us=None, yids=None, c=None, p0=None):
    """
    pred = list2predict(['exp(-p1*1)+exp(-p2*1)', 'exp(-p1*2)+exp(-p2*2)', 'exp(-p1*1)-exp(-p2*1)'],
                        pids=['p1','p2'], p0=None)
    
    pred = list2predict(['(k1f*C1-k1r*X1)-(k2f*X1-k2r*X2)', 
                         '(k2f*X1-k2r*X2)-(k3f*X2-k3r*C2)'],
                        uids=['X1','X2'],
                        us=butil.get_product([1,2,3],[1,2,3]),
                        pids=['k1f','k1r','k2f','k2r','k3f','k3r'], 
                        c={'C1':2,'C2':1})
                        
    Input:
        c: a mapping
    """
    if c is not None:
        l = [exprmanip.sub_for_vars(s, c) for s in l]
    
    ystr = str(l).replace("'", "")
    ycode = compile(ystr, '', 'eval')
    
    def f(p):
        return np.array(eval(ycode, dict(zip(pids, p)), mathsubs))
    
    jaclist = []
    for s in l:
        jacrow = [exprmanip.simplify_expr(exprmanip.diff_expr(s, pid))
                  for pid in pids]
        jaclist.append(jacrow)
        
    if us is not None:
        jaclist = [[[exprmanip.sub_for_vars(jacentry, dict(zip(uids, u))) 
                     for jacentry in jacrow] 
                    for jacrow in jaclist]
                   for u in us]
        jaclist = butil.flatten(jaclist, depth=1)       

    jacstr = str(jaclist).replace("'", "")
    jaccode = compile(jacstr, '', 'eval')

    def Df(p):
        return np.array(eval(jaccode, dict(zip(pids, p)), mathsubs))
    
    if p0 is None:
        p0 = [1] * len(pids)
        
    if yids is None:
        yids = ['y%d'%i for i in range(1, len(l)+1)]
        if us is not None:
            uids = ['u%d'%i for i in range(1, len(us)+1)]
            yids = butil.get_product(yids, uids)
        
    return Predict(f=f, Df=Df, p0=p0, pids=pids, yids=yids)    
Exemple #4
0
 def add(self, row=None, **kwargs):
     """
     Use sparingly as it makes a copy each time ? 
     
     Time it: FIXME **
     
     Input:
         row: {list-like, map-like}
     """
     if row is None:
         row = kwargs
     if isinstance(row, Mapping):
         row = butil.flatten([row[vartype] for vartype in self.vartypes])
     self.loc[self.nrow] = row
 def add(self, row=None, **kwargs):
     """
     Use sparingly as it makes a copy each time ? 
     
     Time it: FIXME **
     
     Input:
         row: {list-like, map-like}
     """
     if row is None:
         row = kwargs
     if isinstance(row, Mapping):
         row = butil.flatten([row[vartype] for vartype in self.vartypes])
     self.loc[self.nrow] = row
Exemple #6
0
 def __init__(self, data=None, index=None, columns=None, **kwargs):
     """Make a *simple* or *composite* ensemble.
     
     Simple ensembles have ``pandas.Index`` as columns, while
     composite ensembles have ``pandas.MultiIndex`` as columns.
      
     Input:
         varids: {list-like, map-like}
     """
     if isinstance(columns, OD):
         columns = [[(vartype, varid) for varid in varids] for
                    vartype, varids in columns.items()]
         columns = butil.flatten(columns, depth=1)
         columns = pd.MultiIndex.from_tuples(columns)
     super(DF, self).__init__(data=data, index=index, columns=columns, 
                              **kwargs)
     self.index.name = 'step'
Exemple #7
0
def get_predict(net, expts, **kwargs_ss):
    """
    """
    varids = list(set(butil.flatten(expts['varids'])))
    if set(varids) <= set(net.xids):
        vartype = 's'
        idxs = [idx for idx, xid in enumerate(net.xids) if xid in varids]
    elif set(varids) <= set(net.Jids):
        vartype = 'J'
        idxs = [idx for idx, Jid in enumerate(net.Jids) if Jid in varids]
    else:
        vartype = 'sJ'
        xJids = net.xids + net.Jids
        idxs = [idx for idx, xJid in enumerate(xJids) if xJid in varids]

    net0 = net.copy()
    if not net0.compiled:
        net0.compile()
    nets = [net0.perturb(cond) for cond in expts.conds]
    [net.get_Ep_str() for net in nets]
    [net.get_Ex_str() for net in nets]

    L, Nr = net.L.values, net.Nr.values

    def f(p):
        y = []
        for net in nets:
            net.update_optimizable_vars(p)
            s = get_s(net, **kwargs_ss)
            if vartype == 's':
                y_cond = s[idxs].tolist()
            if vartype == 'J':
                y_cond = [
                    net.evaluate_expr(net.reactions[idx].kineticLaw)
                    for idx in idxs
                ]
            if vartype == 'sJ':
                sJ = np.concatenate(
                    (get_s(net, **kwargs_ss), get_J(net, **kwargs_ss)))
                y_cond = sJ[idxs].tolist()
            y.extend(y_cond)
        return np.array(y)

    def Df(p):
        jac = []
        for net in nets:
            net.update_optimizable_vars(p)
            if vartype == 's':
                #jac_cond = get_Rs(net, p, Nr, L, to_mat=1, **kwargs_ss).loc[varids].dropna()  # why dropna?
                jac_cond = get_Rs(net, Nr, L, **kwargs_ss)[idxs]
            if vartype == 'J':
                jac_cond = get_RJ(net, Nr, L, **kwargs_ss)[idxs]
            if vartype == 'sJ':  # to be refined
                R = np.vstack(
                    (get_Rs(net, Nr, L,
                            **kwargs_ss), get_RJ(net, Nr, L, **kwargs_ss)))
                jac_cond = R[idxs]
            jac.extend(jac_cond.tolist())
        return np.array(jac)

    pred = predict.Predict(f=f,
                           Df=Df,
                           p0=net.p0,
                           pids=net.pids,
                           yids=expts.yids,
                           expts=expts,
                           nets=nets)

    return pred
Exemple #8
0
def get_stoich_mat(net=None,
                   rxnid2stoich=None,
                   only_dynvar=True,
                   integerize=False,
                   to_mat=True):
    """Return the stoichiometry matrix (N) of the given network or 
    dict rxnid2stoich. Rows correspond to species, and columns correspond to 
    reactions.
    
    Input:
        rxnid2stoich: eg, {'R1':{'A1:1}, 'R2':{'A1':1}}; 
                      net & rxnid2stoich: one and only one should be given
        only_dynvar: if True, use *dynamic* species as rows (keep out 
                        constant/buffered species);
                     if False, use species as row
        integerize: if True, make all stoichcoefs integers
    """
    if net:
        try:
            ## assume network structure has not changed and
            # precalculated N is up-to-date
            return net.stoich_mat
        except (AttributeError, ValueError):
            if only_dynvar:
                rowvarids = net.xids
            else:
                rowvarids = net.spids
            N = Matrix(np.zeros((len(rowvarids), len(net.rxnids))), rowvarids,
                       net.rxnids)
            for spid in rowvarids:
                for rxnid in net.rxnids:
                    try:
                        stoichcoef = net.rxns[rxnid].stoichiometry[spid]
                        # sometimes stoichcoefs are strings
                        if isinstance(stoichcoef, str):
                            stoichcoef = net.evaluate_expr(stoichcoef)
                        N.loc[spid, rxnid] = stoichcoef
                    except KeyError:
                        pass  # mat[i,j] remains zero

    if rxnid2stoich:
        rxnids = rxnid2stoich.keys()
        spids = []
        for stoich in rxnid2stoich.values():
            for spid, stoichcoef in stoich.items():
                if int(stoichcoef) != 0 and spid not in spids:
                    spids.append(spid)
        N = Matrix(np.zeros((len(spids), len(rxnids))), spids, rxnids)
        for spid in spids:
            for rxnid in rxnids:
                try:
                    N.loc[spid, rxnid] = rxnid2stoich[rxnid][spid]
                except KeyError:
                    pass  # mat[i,j] remains zero

    # make all stoichcoefs integers by first expressing them in fractions
    if integerize:
        for i in range(N.ncol):
            col = N.iloc[:, i]
            nonzeros = [num for num in butil.flatten(col) if num]
            denoms = [
                fractions.Fraction(nonzero).limit_denominator().denominator
                for nonzero in nonzeros
            ]
            denom = np.prod(list(set(denoms)))
            N.iloc[:, i] = col * denom

    if net is not None:
        net.stoich_mat = N

    if not to_mat:
        N = N.values
    return N
Exemple #9
0
def get_ss_flux_mat(net, integerize=True, to_mat=True):
    """
    Input:
        net & stoichmat: one and only one of them should be given
        integerize: does not work very well so far: eg, for N = 
        
              RBCO  PGAK  GAPDH  REGN  RK  PGAT  GAPT
        RuBP    -1     0      0     0   1     0     0
        PGA      2    -1      0     0   0    -1     0
        BPGA     0     1     -1     0   0     0     0
        GAP      0     0      1    -5   0     0    -1
        Ru5P     0     0      0     3  -1     0     0, 
        
        or: N = array([[-1.,  0.,  0.,  0.,  1.,  0.,  0.],
                       [ 2., -1.,  0.,  0.,  0., -1.,  0.],
                       [ 0.,  1., -1.,  0.,  0.,  0.,  0.],
                       [ 0.,  0.,  1., -5.,  0.,  0., -1.],
                       [ 0.,  0.,  0.,  3., -1.,  0.,  0.]])
        K should be:
        RBCO    3   0
        PGAK    0   1
        GAPDH   0   1
        REGN    1   0
        RK      3   0
        PGAT    6  -1
        GAPT   -5   1
        
        But this code, using "integerize" gives: 
        RBCO    3   0
        PGAK    0   1
        GAPDH   0   1
        REGN    0   0
        RK      3   0
        PGAT    6  -1
        GAPT   -5   1

        For this reason, "integerize" should not be used for now unless debugged 
        and more testings have been done, and integer N is required for now.
                      
    """
    try:
        K = net.ss_flux_mat
        N = net.N
        if (K.ncol == 0 and N.rank == N.ncol) or\
            ((N*K).is_zero() and K.ncol + N.rank == N.ncol):
            return K
        else:
            raise ValueError("")
    except (AttributeError, ValueError):
        ## The following codes compute the INTEGER basis of right null space
        ## of stoichiometry matrix.

        ## convert the matrix into a string recognizable by sage
        N = net.N
        N_int = Matrix.astype(N, np.int)

        if np.allclose(N, N_int):
            N = N_int
        else:
            raise ValueError("N is not in integers.")

        if N.rank == N.ncol:
            K = Matrix(None, net.rxnids)
        else:
            matstr = re.sub('\s|[a-z]|\(|\)', '', np.matrix(N).__repr__())

            ## write a (sage) python script ".tmp_sage.py"
            # for more info of the sage commands:
            # http://www.sagemath.org/doc/faq/faq-usage.html#how-do-i
            # -import-sage-into-a-python-script
            # http://www.sagemath.org/doc/tutorial/tour_linalg.html
            f = open('.tmp_sage.py', 'w')
            f.write('from sage.all import *\n\n')
            if np.float in N.dtypes.values:
                f.write('A = matrix(RR, %s)\n\n' % matstr)  # real field
            else:
                f.write('A = matrix(ZZ, %s)\n\n' % matstr)  # integer field
            f.write('print kernel(A.transpose())'
                    )  # return right nullspace vectors
            f.close()

            ## call sage and run .tmp_sage.py
            out = subprocess.Popen(['sage', '-python', '.tmp_sage.py'],
                                   stdout=subprocess.PIPE)

            ## process the output from sage
            vecstrs = out.communicate()[0].split('\n')[2:-1]
            #vecs = [eval(re.sub('(?<=\d)\s*(?=\d|-)', ',', vec))
            #        for vec in vecstrs]
            vecs = [
                filter(None,
                       vec.strip('[]').split(' ')) for vec in vecstrs
            ]
            try:
                vecs = [[int(elem) for elem in vec if elem] for vec in vecs]
            except ValueError:
                vecs = [[float(elem) for elem in vec if elem] for vec in vecs]
            fdids = ['J%d' % idx for idx in range(1, len(vecs) + 1)]
            K = Matrix(np.transpose(vecs), net.rxnids, fdids)

        if integerize:  # buggy, see the docstring FIXME **
            for i in range(K.ncol):
                col = K.iloc[:, i]
                nonzeros = [num for num in butil.flatten(col) if num]
                denoms = [
                    fractions.Fraction(nonzero).limit_denominator(
                        1000).denominator for nonzero in nonzeros
                ]
                denom = np.prod(list(set(denoms)))
                K.iloc[:, i] = np.asarray(col * denom, dtype='int')

        assert (N*K).is_zero(), "The calculated K is not really in"\
        "the nullspace of N!"

        net.ss_flux_mat = K

        if not to_mat:
            K = K.values

        return K
Exemple #10
0
def get_stoich_mat(net=None, rxnid2stoich=None, only_dynvar=True, 
                   integerize=True):
    """Return the stoichiometry matrix (N) of the given network or 
    dict rxnid2stoich. Rows correspond to species, and columns correspond to 
    reactions.
    
    Input:
        rxnid2stoich: eg, {'R1':{'A1:1}, 'R2':{'A1':1}}; 
                      net & rxnid2stoich: one and only one should be given
        only_dynvar: if True, use *dynamic* species as rows (keep out 
                        constant/buffered species);
                     if False, use species as row
        integerize: if True, make all stoichcoefs integers
    """
    if net:
        try:
            N = net.stoich_mat
            
            ## need to check what structures are examined... FIXME
            if net._get_structure() == net._last_structure:
                return N
            else:
                net.compile()  # it does the assignment net._last_structure = net._get_structure()
                raise ValueError("Net's structure has been changed and\
                                  N potentially outdated.")
        except (AttributeError, ValueError):
            if only_dynvar:
                rowvarids = net.xids
            else:
                rowvarids = net.spids
            N = Matrix(np.zeros((len(rowvarids), len(net.rxnids))),
                       rowvarids, net.rxnids)
            for spid in rowvarids:
                for rxnid in net.rxnids:
                    try:
                        stoichcoef = net.rxns[rxnid].stoichiometry[spid]
                        # sometimes stoichcoefs are strings
                        if isinstance(stoichcoef, str):
                            stoichcoef = net.evaluate_expr(stoichcoef)
                        N.loc[spid, rxnid] = stoichcoef
                    except KeyError:
                        pass  # mat[i,j] remains zero

    if rxnid2stoich:
        rxnids = rxnid2stoich.keys()
        spids = []
        for stoich in rxnid2stoich.values():
            for spid, stoichcoef in stoich.items():
                if int(stoichcoef) != 0 and spid not in spids:
                    spids.append(spid)
        N = Matrix(np.zeros((len(spids), len(rxnids))), spids, rxnids)
        for spid in spids:
            for rxnid in rxnids:
                try:
                    N.loc[spid, rxnid] = rxnid2stoich[rxnid][spid]
                except KeyError:
                    pass  # mat[i,j] remains zero
    
    # make all stoichcoefs integers by first expressing them in fractions
    if integerize: 
        for i in range(N.ncol):
            col = N.iloc[:,i]
            nonzeros = [num for num in butil.flatten(col) if num]
            denoms = [fractions.Fraction(str(round(nonzero,2))).denominator 
                      for nonzero in nonzeros]
            denom = np.prod(list(set(denoms)))
            N.iloc[:,i] = col * denom
    
    if net is not None:
        net.stoich_mat = N
    return N