def rotation(phi, psi=None): if psi is None: c = cos(phi) s = sin(phi) return Matrix([[c, -s, 0], [s, c, 0], [0, 0, 1]]) else: den = (phi**2 + psi**2)**.5 phi /= den psi /= den return Matrix([[phi, -psi, 0], [psi, phi, 0], [0, 0, 1]])
def get_link_mat(net): """ L0: L = [I ] [L0] N = L * Nr """ I = Matrix.eye(net.ixids) L0 = get_reduced_link_mat(net) L = Matrix(pd.concat((I, L0))) return L
def get_param_elas_mat(net, p=None, normed=False): """ """ net.update(p=p, t=np.inf) ns = net.namespace.copy() ns.update(net.varvals.to_dict()) if not hasattr(net, 'Ep_str'): Ep_code = get_Ep_str(net)[1] else: Ep_code = net.Ep_code Ep = Matrix(eval(Ep_code, ns), net.vids, net.pids) if normed: return Ep.normalize(net.v, net.p) else: return Ep
def get_param_elas_mat(net, p=None, normed=False): """ """ net.update(p=p, t=np.inf) ns = net.namespace.copy() ns.update(net.varvals.to_dict()) if not hasattr(net, 'Ep_str'): Ep_code = get_Ep_str(net)[1] else: Ep_code = net.Ep_code Ep = Matrix(eval(Ep_code, ns), net.rateids, net.pids) if normed: return Ep.normalize(net.J, net.p) else: return Ep
def get_concn_elas_mat(net, p=None, normed=False): """ FIXME ***: compile or generate dynamic Python functions """ net.update(p=p, t=np.inf) ns = net.namespace.copy() # without copy, the namespace is contaminated ns.update(net.vals.to_dict()) if not hasattr(net, 'Ex_code'): Ex_code = get_Ex_str(net)[1] else: Ex_code = net.Ex_code Es = Matrix(eval(Ex_code, ns), net.rateids, net.xids) if normed: return Es.normalize(net.J, net.s) else: return Es
def _calc_current_vertices(self): x, y, kx, ky = self.x_p, self.y_p, self.kx, self.ky c = cos(self.alpha) s = sin(self.alpha) self.vertices_current = Matrix([[kx * c, -ky * s, x], [kx * s, ky * c, y], [0, 0, 1] ]) * self.vertices_initial
def Df(p=None, to_mat=False): if p is None: p = p0 jac = _Df(p) if to_mat: jac = Matrix(jac, index=yids, columns=pids) return jac
def _calc_matrices(self): kv = self.N.normalised() iv = self.Top.cross_product(self.N).normalised() jv = kv.cross_product(iv) self.__S_w_to_v = Matrix([ [iv.x, iv.y, iv.z, -iv.dot(self.Ov)], [jv.x, jv.y, jv.z, -jv.dot(self.Ov)], [kv.x, kv.y, kv.z, -kv.dot(self.Ov)], [0, 0, 0, 1] ]) self.__S_v_to_p = Matrix([ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1 / self.D, 1] ]) self.__S_w_to_p = self.__S_v_to_p * self.__S_w_to_v
def mapping(self, raw_train_ratings): uid_dict = {} iid_dict = {} current_u_index = 0 current_i_index = 0 row = [] col = [] data = [] for urid, irid, r, timestamp in raw_train_ratings: try: uid = uid_dict[urid] except KeyError: uid = current_u_index uid_dict[urid] = current_u_index current_u_index += 1 try: iid = iid_dict[irid] except KeyError: iid = current_i_index iid_dict[irid] = current_i_index current_i_index += 1 row.append(uid) col.append(iid) data.append(r) sparse_matrix = csr_matrix((data, (row, col))) return Matrix(sparse_matrix, uid_dict, iid_dict)
def get_concn_elas_mat(net, p=None, normed=False): """ FIXME ***: compile or generate dynamic Python functions """ net.update(p=p, t=np.inf) ns = net.namespace.copy() # without copy, the namespace is contaminated ns.update(net.varvals.to_dict()) if not hasattr(net, 'Ex_code'): Ex_code = get_Ex_str(net)[1] else: Ex_code = net.Ex_code Es = Matrix(eval(Ex_code, ns), net.vids, net.xids) if normed: return Es.normalize(net.v, net.s) else: return Es
def jws2mat(filepath, name=None): """Parse the output file of JWS online. Input: filepath: name: str; 'Cs', 'nCs', 'CJ', 'nCJ' """ fh = open(filepath) lines = fh.readlines() fh.close() if name is None: name = filepath.split('/')[-1].split('_')[0] if name == 'nEs': add_prefix_row = lambda varid: 'log_v_' + varid add_prefix_col = lambda varid: 'log_' + varid elif name == 'nCs': add_prefix_row = lambda varid: 'log_' + varid add_prefix_col = lambda varid: 'log_v_' + varid else: add_prefix_row = lambda varid: varid add_prefix_col = lambda varid: varid colvarids = [add_prefix_col(s.strip()) for s in lines[0].split(',')[1:]] rowvarids = [] mat = [] for line in lines[1:]: rowvarids.append(add_prefix_row(line.split(',')[0])) mat.append([float(s) for s in line.split(',')[1:]]) mat = Matrix(mat, rowvarids, colvarids) return mat
def copasi2mats(filepath, name=None): """Parse the output file of Copasi. Input: filepath: name: """ _trim0 = lambda s: s.replace('(','').replace(')','') _trim = lambda s: _trim0(s) if isinstance(s,str) else [_trim0(_) for _ in s] fh = open(filepath) lines = fh.readlines() fh.close() parts = ''.join(lines).split('\n\n')[2:] name2mat = OD() try: for part in parts: lines_part = part.split('\n') lines_mat = lines_part[4:] colvarids = _trim(lines_mat[0].split('\t')[1:]) mat = [] rowvarids = [] for line in lines_mat[1:]: rowvarids.append(_trim(line.split('\t')[0])) mat.append([float(s) for s in line.split('\t')[1:]]) name2mat[lines_part[1]] = Matrix(mat, rowvarids, colvarids) except: pass if name: return name2mat[name] else: return name2mat
def Dr(p=None, to_mat=False): if p is None: p = pred.p0 jac_f = pred.Df(p) jac_r = -(jac_f.T / sigma).T ## corrected if to_mat: jac_r = Matrix(jac_r, pred.yids, pred.pids) return jac_r
def _get_smat(p, scheme, cutoff_singval, stepscale, temperature): if scheme == 'jtj': jac = Dfunc(p) jtj = jac.T * jac smat = _hess2smat(jtj, cutoff_singval, stepscale, temperature) if scheme == 'eye': smat = Matrix.eye(func.pids) * stepscale return smat
def _get_smat(p, scheme, cutoff_singval, stepscale, temperature): if scheme == 'jtj': jac = Dfunc(p) jtj = np.dot(jac.T, jac) smat = _hess2smat(jtj, cutoff_singval, stepscale, temperature) if scheme == 'eye': smat = Matrix.eye(func.pids) * stepscale return smat
def get_flux_ctrl_mat(net, p=None, normed=False): """ """ net.update(p=p, t=np.inf) I, Es, Cs = Matrix.eye(net.Jids, net.vids), net.Es, net.Cs CJ = I + (Es * Cs).ch_rowvarids(net.Jids) if normed: return CJ.normalize(net.J, net.v) else: return CJ
def get_flux_ctrl_mat(net, p=None, normed=False): """ """ net.update(p=p, t=np.inf) I, Es, Cs = Matrix.eye(net.fluxids, net.rateids), net.Es, net.Cs CJ = I + (Es * Cs).ch_rowvarids(net.fluxids) if normed: return CJ.normalize(net.J, net.v) else: return CJ
def get_reduced_link_mat(net, to_mat=True): """ L0: L = [I ] [L0] """ if len(net.ixids) == len(net.xids): L0 = Matrix(columns=net.ixids) else: L0 = -net.P.loc[:, net.ixids].ch_rowvarids(net.dxids) if not to_mat: L0 = L0.values return L0
def get_link_mat(net): """ L0: L = [I ] [L0] N = L * Nr """ I = Matrix.eye(net.ixids) if len(net.ixids) == len(net.xids): L = I else: L0 = -net.P.loc[:, net.ixids].ch_rowvarids(net.dxids) L = Matrix(pd.concat((I, L0))) return L
def fit_lm_scipy(res, p0=None, in_logp=True, **kwargs): """ """ if p0 is None: p0 = res.p0 else: p0 = Series(p0, res.pids) if in_logp: res = res.get_in_logp() p0 = p0.log() else: res = res kwargs = butil.get_submapping(kwargs, keys=[ 'full_output', 'col_deriv', 'ftol', 'xtol', 'gtol', 'maxfev', 'epsfcn', 'factor', 'diag' ]) kwargs_ls = kwargs.copy() kwargs_ls['full_output'] = True p, cov, infodict, mesg, ier = leastsq(res, p0, Dfun=res.Dr, **kwargs_ls) if in_logp: p = np.exp(p) # cov = ... FIXME *** r = Series(infodict['fvec'], res.rids) cost = _r2cost(r) covmat = Matrix(cov, res.pids, res.pids) nfcall = infodict['nfev'] fit = Fit(cost=cost, p=p, pids=res.pids, covmat=covmat, nfcall=nfcall, r=r, message=mesg, ier=ier) return fit
def get_jac_mat(net, p=None, x=None): """ Return the jacobian matrix (M) of the network, which, _in the MCA context_, is the jacobian of the independent vector field dxi/dt = Nr * v(xi,xd,p) (so that M is invertible). """ if x is None: net.update(p=p, t=np.inf) L, Es, Nr = net.L, net.Es, net.Nr.ch_colvarids(net.vids) M = Nr * Es * L else: if p is not None: net.update(p=p) Exstr = get_Ex_str(net)[0] x = Series(x, net.xids) Ex = Matrix(eval(Exstr, dict(net.varvals.items()+x.items())), net.rxnids, net.xids) M = net.N * Ex return M
def get_RJ(net, Nr, L, p=None, to_mat=False, **kwargs_ss): if p is not None: net.update_optimizable_vars(p) if not hasattr(net, 'Ep_code'): net.get_Ep_str() net.get_Ex_str() set_ss(net, **kwargs_ss) # also sets net.x = s (crucial) ns = net.namespace.copy() ns.update(net.varvals.to_dict()) Ep = eval(net.Ep_code, ns) Es = eval(net.Ex_code, ns) jac = np.dot(np.dot(Nr, Es), L) Cs = -np.dot(np.dot(L, np.linalg.inv(jac)), Nr) CJ = np.eye(len(net.rxns)) + np.dot(Es, Cs) RJ = np.dot(CJ, Ep) if to_mat: RJ = Matrix(RJ, net.Jids, net.pids) return RJ
def mapping(train_ratings): uid_dict = {} # {"编号":"下标(编号-1)"} iid_dict = {} row = [] # user 下标 col = [] # item 下标 data = [] for uid, iid, r, timestamp in train_ratings: try: uid_index = uid_dict[uid] except KeyError: uid_index = uid - 1 uid_dict[uid] = uid_index try: iid_index = iid_dict[iid] except KeyError: iid_index = iid - 1 iid_dict[iid] = iid_index row.append(uid_index) col.append(iid_index) data.append(r) sparse_matrix = csr_matrix((data, (row, col))) return Matrix(sparse_matrix, uid_dict, iid_dict)
def rotation_y(phi): c = cos(phi) s = sin(phi) return Matrix([[c, 0, s, 0], [0, 1, 0, 0], [-s, 0, c, 0], [0, 0, 0, 1]])
X[k] = np.linalg.solve(np.dot(Y_u.T, Y_u) + reg_I, np.dot(Y.T, r)) # X[k] = np.linalg.solve(np.dot(Y.T, Y) + reg_I, np.dot(Y.T, r)) def _prepare(self): self.user_num = self.train_dataset.matrix.shape[0] self.item_num = self.train_dataset.matrix.shape[1] self.X = np.random.normal(size=(self.user_num, self.n_factors)) self.Y = np.random.normal(size=(self.item_num, self.n_factors)) def _iteration(self): self.alternative(self.X, self.Y, True) self.alternative(self.Y, self.X, False) def _pred(self): return np.dot(self.X, self.Y.T) def predict(self, u, i): est = np.dot(self.X[u, :], self.Y[i, :]) return est if __name__ == '__main__': from util.matrix import Matrix data = sparse.csc_matrix(np.random.randint(0, 5, (5, 5))) print(data) ex = ExplicitALS() ex.train(Matrix(data)) print(data.A) print(ex._pred())
def fit_lm_custom(self, p0=None, in_logp=True, maxnstep=1000, ret_full=False, ret_steps=False, disp=False, lamb0=0.001, tol=1e-6, k_up=10, k_down=10, ndone=5, **kwargs): """ Input: k_up and k_down: parameters used in tuning lamb at each step; in the traditional scheme, typically k_up = k_down = 10; in the delayed gratification scheme, typically k_up = 2, k_down = 10 (see, [1]) grad C = Jt * r J = U * S * Vt ______ ______ | | | | ______ ______ | | | | | | | | | J | = | U | | S | | Vt | | | | | |______| |______| |______| |______| Vt * V = V * Vt = I Ut* U = I =/= U * Ut JtJ = (V * S * Ut) * (U * S * Vt) = V * S^2 * Vt ______ ____________ ______ | | | | | | ______ | | | | | | | | | | = | | | | | | | | | | | | |______| |______| |____________| |______| Gradient Descent step: delta p = - grad C Gauss Newton step: delta p = - (JtJ).I * grad C Levenberg Marquardt step: delta p = - (JtJ + lamb * I).inv * grad C = - (V * (S^2 + lamb * I) * Vt).inv * Jt * r = - (V * (S^2 + lamb * I).inv * Vt) * V * S * Ut * r = - V * (S^2 + lamb * I).inv * S * Ut * r References: [1] Transtrum [2] Numerical Recipes """ if p0 is None: p0 = self.p0 else: p0 = Series(p0, self.pids) if in_logp: res = self.get_in_logp() p0 = p0.log() else: res = self if maxnstep is None : maxnstep = len(res.pids) * 100 nstep = 0 nfcall = 0 nDfcall = 0 p = p0 lamb = lamb0 done = 0 accept = True convergence = False r = res(p0) cost = _r2cost(r) nfcall += 1 if ret_steps: ps = DF([p0], columns=res.pids) deltaps = DF(columns=res.pids) costs = Series([cost], name='cost') lambs = Series([lamb], name='lamb') ps.index.name = 'step' costs.index.name = 'step' lambs.index.name = 'step' while not convergence and nstep < maxnstep: if accept: jac = res.Dr(p) U, S, Vt = jac.svd(to_mat=True) nDfcall += 1 deltap = - Vt.T * (S**2 + lamb * Matrix.eye(res.pids)).I * S * U.T * r deltap = deltap[0] # convert 1-d DF to series p2 = p + deltap nstep += 1 r2 = res(p2) cost2 = _r2cost(r2) nfcall += 1 if np.abs(cost - cost2) < max(tol, cost * tol): done += 1 if cost2 < cost: accept = True lamb /= k_down p = p2 r = r2 cost = cost2 else: accept = False lamb *= k_up if ret_steps: ps.loc[ps.nrow] = p deltaps.loc[deltaps.nrow] = deltap costs.loc[costs.size] = cost lambs.loc[lambs.size] = lamb if done == ndone: convergence = True # lamb = 0 if in_logp: p = p.exp() if ret_steps: ps = np.exp(ps) ps.columns = self.pids out = Series(OD([('p', p), ('cost', cost)])) if ret_full: out.nfcall = nfcall out.nDfcall = nDfcall out.convergence = convergence out.nstep = nstep if ret_steps: out.ps = ps out.deltaps = deltaps out.costs = costs out.lambs = lambs return out
s = sin(phi) return Matrix([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]]) def rotation_y(phi): c = cos(phi) s = sin(phi) return Matrix([[c, 0, s, 0], [0, 1, 0, 0], [-s, 0, c, 0], [0, 0, 0, 1]]) def rotation_z(phi): c = cos(phi) s = sin(phi) return Matrix([[c, -s, 0, 0], [s, c, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) def scaling(kx, ky=None, kz=None): if ky is None and kz is None: ky = kz = kx return Matrix([[kx, 0, 0, 0], [0, ky, 0, 0], [0, 0, kz, 0], [0, 0, 0, 1]]) mirroring_x = Matrix([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]) mirroring_y = Matrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]) mirroring_z = Matrix([[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
def _calc_current_vertices(self): c, s = self.cos, self.sin self.vertices_current = Matrix([[c, -s, self.x], [s, c, self.y], [0, 0, 1]]) * self.vertices_initial
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
def rotation_z(phi): c = cos(phi) s = sin(phi) return Matrix([[c, -s, 0, 0], [s, c, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
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
def rotation_x(phi): c = cos(phi) s = sin(phi) return Matrix([[1, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, 1]])
def translation(x, y, z): return Matrix([[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]])
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
def get_pool_mul_mat(net, to_mat=True): """ Return a matrix whose row vectors are multiplicities of dynamic variables in conservation pools. Mathematically, the matrix has rows spanning the left null space of the stoichiometry matrix of the network. The function is computationally costly, because it calls *sage* to perform matrix computations over the integer ring. (Note that the matrix is converted to floats before being returned.) """ try: P = net.pool_mul_mat N = net.N if (P.nrow == 0 and N.rank == N.nrow) or\ ((P*N).is_zero() and P.nrow + N.rank == N.nrow): return P else: raise ValueError("net has P but its N has changed.") except (AttributeError, ValueError): ## The following codes compute the INTEGER basis of left null space # of stoichiometry matrix. ## Convert the matrix into a string recognizable by sage. N = net.N if N.rank == N.nrow: P = Matrix(None, columns=net.xids) 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 A.kernel()') # this returns the left 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 ] #poolids = ['Pool%d'%idx for idx in range(1, len(vecs)+1)] poolids = net.xids[-len(vecs):][::-1] P = Matrix(vecs, poolids, N.rowvarids) # Clean things up: so far P can be, eg, # X1 X2 X3 X4 # Pool1 0 0 1 1 # say, adenonine backbone # Pool2 2 1 3 2 # say, phospho group # We want it be the following, via Gaussian row reduction: # X1 X2 X3 X4 # Pool1 2 1 1 0 # Pool2 -2 -1 0 1 # so that X3 and X4 as the dependent dynvars can be easily # selected and expressed as the linear combinations of # independent dynvars P = P.ix[:, ::-1].rref().ix[::-1, ::-1] net.pool_mul_mat = P if not to_mat: p = P.values return P
def scaling(kx, ky=None, kz=None): if ky is None and kz is None: ky = kz = kx return Matrix([[kx, 0, 0, 0], [0, ky, 0, 0], [0, 0, kz, 0], [0, 0, 0, 1]])
def fit_lm_custom( res, p0=None, in_logp=True, maxnstep=1000, disp=False, #ret_full=False, ret_steps=False, lamb0=1e-3, tol=1e-6, k_up=10, k_down=10, ndone=5, **kwargs): """ Input: k_up and k_down: parameters used in tuning lamb at each step; in the traditional scheme, typically k_up = k_down = 10; in the delayed gratification scheme, typically k_up = 2, k_down = 10 (see, [1]) grad C = Jt * r J = U * S * Vt ______ ______ | | | | ______ ______ | | | | | | | | | J | = | U | | S | | Vt | | | | | |______| |______| |______| |______| V.T * V = V * V.T = I U.T * U = I =/= U * U.t J.T * J = (V * S * U.T) * (U * S * V.T) = V * S^2 * V.T ______ ____________ ______ | | | | | | ______ | | | | | | | | | | = | | | | | | | | | | | | |______| |______| |____________| |______| Gradient-descent step: delta p = - grad C = - J.T * r Gauss-Newton step: delta p = - (J.T * J).inv * grad C = - (J.T * J).inv * J.T * r Levenberg step: delta p = - (J.T * J + lamb * I).inv * grad C = - (V * (S^2 + lamb * I) * V.T).I * J.T * r = - (V * (S^2 + lamb * I).inv * V.T) * V * S * U.T * r = - V * (S^2 + lamb * I).inv * S * U.T * r References: [1] Transtrum [2] Numerical Recipes """ if p0 is None: p0 = res.p0 else: p0 = Series(p0, res.pids) if in_logp: res = res.get_in_logp() p0 = p0.log() else: res = res if maxnstep is None: maxnstep = len(res.pids) * 100 nstep = 0 nfcall = 0 nDfcall = 0 p = p0 lamb = lamb0 done = 0 accept = True convergence = False r = res(p0) cost = _r2cost(r) nfcall += 1 ps = [p0] deltaps = [] costs = [cost] lambs = [lamb] while not convergence and nstep < maxnstep: if accept: ## FIXME *** jac = res.Dr(p, to_mat=True) U, S, Vt = jac.svd(to_mat=True) nDfcall += 1 deltap = -Vt.T * (S**2 + lamb * Matrix.eye(res.pids)).I * S * U.T * r deltap = deltap[0] # convert 1-d DF to series p2 = p + deltap nstep += 1 if disp: #print nstep print deltap.exp()[:10] print lamb #print p2 #from util import butil #butil.set_global(p=p, deltap=deltap, p2=p2, nstep=nstep) r2 = res(p2) cost2 = _r2cost(r2) nfcall += 1 if np.abs(cost - cost2) < max(tol, cost * tol): done += 1 if cost2 < cost: accept = True lamb /= k_down p = p2 r = r2 cost = cost2 else: accept = False lamb *= k_up ps.append(p) deltaps.append(deltap) costs.append(cost) lambs.append(lamb) if done == ndone: convergence = True # lamb = 0 if in_logp: ps = np.exp(ps) pids = map(lambda pid: pid.lstrip('log_'), res.pids) else: pids = res.pids ## need to calculate cov FIXME *** fit = Fit(costs=costs, ps=ps, pids=pids, lambs=lambs, nfcall=nfcall, nDfcall=nDfcall, convergence=convergence, nstep=nstep) return fit