void free(void *x) { sylvester(x); *(gulong *)x = MAGIC2; __libc_free((char *)x - sizeof(struct header)); }
void * realloc(void *x, size_t sz) { if (x != 0) { sylvester(x); x = (void *)((char *)x - sizeof(struct header)); } if ((x = __libc_realloc(x, sizeof(struct header) + sz + CAGE)) == 0) return 0; ((struct header *)x)->magic = MAGIC1 ^ sz; ((struct header *)x)->size = sz; memset((char *)x + sizeof(struct header) + sz, TWEETY, CAGE); return ((char *)x + sizeof(struct header)); }
/** * Calcule le resultant des polynomes bivaries PY et QY * Appeler nb_zeros et del_zeros en sortie pour avoir le resultant sans les premiers coeffs nuls * @param resultant le resultant de PY et QY de taille 2*deg_P*deg_Q+1 * @param deg_P le degre du polynome PY en Y (nb de colonnes) * @param deg_Q degre de QY en Y * @param degres_PY liste des degres en X des coefficients de PY * @param degres_QY liste des degres en X des corfficients de QY */ void resultant(mpz_t *resultant, mpz_t **PY, mpz_t **QY, int deg_P, int deg_Q, int *degres_PY, int *degres_QY, mpz_t mod){ printf("resultant\n"); int i,j, borne; int matrix_length=deg_P+deg_Q; int matrix_size= matrix_length*matrix_length; /* allocation de la matrice de sylvester */ mpz_t M[matrix_size]; for(i=0; i<matrix_size; i++) mpz_init(M[i]); /* Calcul de la borne superieure sur le degre du resultant */ borne=2*deg_P*deg_Q+1; /* si le modulo est trop petit, on ne peut pas choisir assez de valeurs pour l interpolation */ if(mpz_cmp_si(mod, borne)<=0){ printf("Modulo trop petit !\n"); exit(0); } printf("borne = %d\n", borne); /* Choix des valeurs d interpolation*/ mpz_t values[borne]; for(i=0; i<borne; i++){ mpz_init_set_si(values[i], i); /*printf("values[%d] = %ld", i, mpz_get_si(values[i]));*/ } /* initialisation de P, Q et du tableau des determinant */ /*printf("\nfin init values\n");*/ mpz_t P[deg_P+1], Q[deg_Q+1]; for(i=0; i<deg_P+1; i++){ mpz_init(P[i]); } for(i=0; i<deg_Q+1; i++){ mpz_init(Q[i]); } /* determinant contiendra les images des points de values pour l interpolation */ mpz_t determinant[borne]; for(i=0;i<borne;i++){ mpz_init(determinant[i]); } /* A chaque iteration, on traite une valeur de values et on calcule le determinant associe */ for(i=0; i<borne; i++){ /* evaluation du polynome en values[i] */ eval_biv(values[i], PY, QY, degres_PY, degres_QY, P, Q, deg_P, deg_Q, mod ); /*print_P(P, deg_P); print_P(Q, deg_Q); printf("appel sylvester\n"); */ /* Calcul de la matrice de Sylvester dans M*/ sylvester(P, Q, deg_P, deg_Q, M); /*printf("matrice de sylvester:\n"); print_M(M, deg_P+deg_Q); printf("appel Gauss\n"); */ /* Appel de Gauss */ /* remplit le determinant associe a values[i] */ gauss(&determinant[i], M, matrix_length, mod); /* on remet M a 0 pour la prochaine iteration */ for(j=0; j<matrix_size; j++) mpz_set_si(M[j], 0); } /* affichage des determinants (avec la fonction d affichage de ploynomes) */ /*printf("determinants : "); print_P(determinant, borne-1);*/ /* appel a Lagrange */ mpz_t res_mod[borne+1]; for(j=0; j<borne+1; j++){ mpz_init(res_mod[j]); } lagrange(resultant, values, determinant, borne-1, mod, res_mod); /*printf("fin lagrange\n");*/ for(j=0; j<borne; j++){ mpz_mod(resultant[j],resultant[j], mod); } }
void CILDMMethod::step(const double & deltaT) { C_INT failed_while = 0; C_INT dim = mData.dim; C_INT fast = 0; C_INT slow = dim - fast; C_INT i, j, k, info_schur = 0; mY_initial.resize(dim); mJacobian_initial.resize(dim, dim); mQ.resize(dim, dim); mR.resize(dim, dim); mQ_desc.resize(dim, dim); mR_desc.resize(dim, dim); mTd.resize(dim, dim); mTdInverse.resize(dim, dim); mQz.resize(dim, dim); mTd_save.resize(dim, dim); mTdInverse_save.resize(dim, dim); mpModel->updateSimulatedValues(mReducedModel); // TO REMOVE : mpModel->applyAssignments(); mpModel->calculateJacobianX(mJacobian, 1e-6, 1e-12); C_INT flag_jacob; flag_jacob = 1; // Set flag_jacob=0 to printing Jacobian // To get the reduced Stoichiometry Matrix; CMatrix<C_FLOAT64> Stoichiom; Stoichiom = mpModel -> getRedStoi(); // const CCopasiVector< CReaction > & reacs = copasiModel->getReactions(); C_INT32 reacs_size = mpModel -> getRedStoi().size(); reacs_size = reacs_size / dim; //TODO what is this? /* the vector mY is the current state of the system*/ C_FLOAT64 number2conc = 1.; //= mpModel->getNumber2QuantityFactor() // / mpModel->getCompartments()[0]->getInitialValue(); //this is an ugly hack that only makes sense if all metabs are in the same compartment //at the moment is is the only case the algorithm deals with CVector<C_FLOAT64> Xconc; //current state converted to concentrations Xconc.resize(dim); for (i = 0; i < dim; ++i) Xconc[i] = mY[i] * number2conc; for (i = 0; i < dim; i++) mY_initial[i] = mY[i]; CVector<C_FLOAT64> Xconc_initial; //current state converted to concentrations Xconc_initial.resize(dim); for (i = 0; i < dim; ++i) Xconc_initial[i] = mY_initial[i] * number2conc; // save initial Jacobian before next time step for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) mJacobian_initial(i, j) = mJacobian(i, j); // Next time step integrationStep(deltaT); mpModel->updateSimulatedValues(mReducedModel); // TO REMOVE : mpModel->applyAssignments(); // Calculate Jacobian for time step control mpModel->calculateJacobianX(mJacobian, 1e-6, 1e-12); #ifdef ILDMDEBUG if (flag_jacob == 0) { std::cout << "Jacobian_next:" << std::endl; std::cout << mJacobian << std::endl; } #endif // to be removed CMatrix<C_FLOAT64> Jacobian_for_test; Jacobian_for_test.resize(dim, dim); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) Jacobian_for_test(i, j) = mJacobian_initial(i, j); // save initial Jacobian before next time step for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) mJacobian_initial(i, j) = mJacobian(i, j); schur(info_schur); #ifdef ILDMDEBUG std::cout << "Eigenvalues of next Jacobian" << std::endl; for (i = 0; i < dim; i++) std::cout << mR(i, i) << std::endl; #endif for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) mJacobian_initial(i, j) = Jacobian_for_test(i, j); //end to be removed for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTd_save(i, j) = 0; mTdInverse_save(i, j) = 0; } for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTd(i, j) = 0; mTdInverse(i, j) = 0; } /** Schur Decomposition of Jacobian (reordered). Output: mQ - transformation matrix mR - block upper triangular matrix (with ordered eigenvalues) */ C_INT failed = 0; // C_INT info_schur = 0; schur(info_schur); // TO DO : move the test to the TSSAMethod if (info_schur) { CCopasiMessage(CCopasiMessage::WARNING, MCTSSAMethod + 5, mTime - deltaT); goto integration; } C_INT flag_schur; flag_schur = 0; #ifdef ILDMDEBUG std::cout << "Eigenvalues of initial Jacobian" << std::endl; for (i = 0; i < dim; i++) std::cout << mR(i, i) << std::endl; if (flag_schur == 1) { std::cout << "Schur Decomposition" << std::endl; std::cout << "mR - block upper triangular matrix :" << std::endl; std::cout << mR << std::endl; } #endif /* If complex eigenvalues */ //BUG 873 if (mR(dim - 1, dim - 1) == mR(dim - 2 , dim - 2)) if (dim == 2) { slow = dim; goto integration; } // No reduction if the smallest eigenvalue is positive if (mR(dim - 1, dim - 1) >= 0) { slow = dim; fast = 0; CCopasiMessage(CCopasiMessage::WARNING, MCTSSAMethod + 6, mTime - deltaT); failed = 1; goto integration; } // C_INT number, k; /** Classical ILDM iterations. The number of slow variables is decreased until the Deuflhard criterium holds */ /* do START slow iterations */ while (slow > 1) { fast = fast + 1; slow = dim - fast; if (fast < dim - 1) if (mR(slow, slow) == mR(slow - 1 , slow - 1)) fast = fast + 1; slow = dim - fast; for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTd_save(i, j) = mTd(i, j); mTdInverse_save(i, j) = mTdInverse(i, j); } C_INT info = 0; failed_while = 0; if (slow == 0) { for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTdInverse(i, j) = mQ(j, i); mTd(i, j) = mQ(i, j); mQz(i, j) = mR(i, j); } } else { /** Solution of Sylvester equation for given slow, mQ,mR Output: mTd, mTdinverse and mQz (mQz is used later for newton iterations) */ sylvester(slow, info); if (info) { CCopasiMessage(CCopasiMessage::WARNING, MCTSSAMethod + 7, slow, mTime - deltaT); failed_while = 1; goto integration; } } /* Check real parts of eigenvalues of Jacobian */ for (i = slow ; i < dim; i++) if (mR(i , i) >= 0) { failed_while = 1; goto integration; } if (fast > 0) mEPS = 1 / fabs(mR(slow , slow)); mCfast.resize(fast); /** Deuflhard Iteration: Prove Deuflhard criteria, find consistent initial value for DAE output: info - if Deuflhard is satisfied for this slow; transformation matrices mTd and mTdinverse */ info = 0; C_INT help; help = 0; deuflhard(slow, info); help = help + 1; failed_while = 0; if (info) { failed_while = 1; goto integration; } } /** end of iterations to find the number of slow modes */ integration: if ((failed == 1) || (failed_while == 1)) { if (slow < dim) { fast = fast - 1; slow = dim - fast; if ((fast >= 1) && (mR(slow - 1, slow - 1) == mR(slow , slow))) fast = fast - 1; slow = dim - fast; for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTd(i, j) = mTd_save(i, j); mTdInverse(i, j) = mTdInverse_save(i, j); } } } mSlow = slow; if (slow == dim) CCopasiMessage(CCopasiMessage::WARNING, MCTSSAMethod + 8, mTime); // test for orthogonality of the slow space C_INT flag_orthog = 1; if (flag_orthog == 0) { CMatrix<C_FLOAT64> orthog_prove; orthog_prove.resize(dim, dim); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) orthog_prove(i, j) = orthog(i, j); } C_INT flag_develop; flag_develop = 0; //1; if (flag_develop == 0) { C_INT info_schur_desc = 0; /** Schur Decomposition of Jacobian (with another sorting: from fast to slow). Output: mQ_desc - transformation matrix mR_desc - block upper triangular matrix (with ordered eigenvalues) */ schur_desc(info_schur_desc); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTd_save(i, j) = mTd(i, j); mTdInverse_save(i, j) = mTdInverse(i, j); } for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTdInverse(i, j) = mQ_desc(j, i); mTd(i, j) = mQ_desc(i, j); } C_INT slow_desc; slow_desc = fast; mat_anal_fast_space(slow_desc); mat_anal_mod_space(slow_desc); CVector<C_FLOAT64> Reac_slow_space_orth; Reac_slow_space_orth.resize(reacs_size); for (i = 0; i < reacs_size; i ++) { Reac_slow_space_orth[i] = 0; for (j = 0; j < dim; j++) { Reac_slow_space_orth[i] = Reac_slow_space_orth[i] + mVfast_space[j] * Stoichiom(j, i); } } for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) { mTd(i, j) = mTd_save(i, j); mTdInverse(i, j) = mTdInverse_save(i, j); } } // end of test // Post Analysis mat_anal_mod(slow); mat_anal_metab(slow); mat_anal_mod_space(slow); mat_anal_fast_space(slow); /** This part corresponds to the investigation of fast and slow reactions. In development at the moment. To activate the calculations take flag_develop = 0; */ if (flag_develop == 0) { CMatrix<C_FLOAT64> Slow_react_contr; Slow_react_contr.resize(dim, reacs_size); CMatrix<C_FLOAT64> Mode_react_contr; Mode_react_contr.resize(dim, reacs_size); CVector<C_FLOAT64> Reac_slow_space; Reac_slow_space.resize(reacs_size); CVector<C_FLOAT64> Reac_fast_space; Reac_fast_space.resize(reacs_size); mReacSlowSpace.resize(reacs_size); //NEW TAB for (i = 0; i < dim; i ++) for (j = 0; j < reacs_size; j++) { Slow_react_contr(i, j) = 0; for (k = 0; k < dim; k++) Slow_react_contr(i, j) = Slow_react_contr(i, j) + mVslow(i, k) * Stoichiom(k, j); } CVector<C_FLOAT64> denom_mode; denom_mode.resize(dim); for (j = 0; j < dim; j++) denom_mode[j] = 0; for (i = 0; i < dim; i++) for (j = 0; j < reacs_size; j++) denom_mode[i] = denom_mode[i] + fabs(Slow_react_contr(i, j)); for (i = 0; i < dim; i++) for (j = 0; j < reacs_size; j++) { if (denom_mode[i] == 0) Mode_react_contr(i, j) = 0; else Mode_react_contr(i, j) = (Slow_react_contr(i, j)) / denom_mode[i] * 100; } CVector<C_FLOAT64> denom_reac; denom_reac.resize(reacs_size); for (j = 0; j < reacs_size; j++) denom_reac[j] = 0; for (i = 0; i < reacs_size; i++) for (j = 0; j < dim; j++) denom_reac[i] = denom_reac[i] + fabs(Slow_react_contr(j, i)); for (i = 0; i < reacs_size; i++) for (j = 0; j < dim; j++) { if (denom_reac[i] == 0) Slow_react_contr(j, i) = 0; else Slow_react_contr(j, i) = (Slow_react_contr(j , i)) / denom_reac[i] * 100; } for (i = 0; i < reacs_size; i ++) { Reac_slow_space[i] = 0; for (j = 0; j < dim; j++) { Reac_slow_space[i] = Reac_slow_space[i] + mVslow_space[j] * Stoichiom(j, i); } } C_FLOAT64 length; length = 0; for (i = 0; i < reacs_size; i++) length = length + fabs(Reac_slow_space[i]); for (i = 0; i < reacs_size; i++) if (length > 0) mReacSlowSpace[i] = Reac_slow_space[i] / length * 100; else mReacSlowSpace[i] = 0; for (i = 0; i < reacs_size; i ++) { Reac_fast_space[i] = 0; for (j = 0; j < dim; j++) Reac_fast_space[i] = Reac_fast_space[i] + mVfast_space[j] * Stoichiom(j, i); } length = 0; for (i = 0; i < reacs_size; i++) length = length + fabs(Reac_fast_space[i]); for (i = 0; i < reacs_size; i++) if (length > 0) Reac_fast_space[i] = Reac_fast_space[i] / length * 100; else Reac_fast_space[i] = 0; #ifdef ILDMDEBUG std::cout << "**********************************************************" << std::endl; std::cout << "**********************************************************" << std::endl; std::cout << std::endl; std::cout << std::endl; #endif mTMP1.resize(reacs_size, dim); mTMP2.resize(reacs_size, dim); mTMP3.resize(reacs_size, 1); for (i = 0; i < dim; i++) for (j = 0; j < reacs_size; j++) { mTMP1(j, i) = Mode_react_contr(i, j); mTMP2(j, i) = Slow_react_contr(i, j); } for (j = 0; j < reacs_size; j++) mTMP3(j, 0) = Reac_fast_space[j]; } // End of reaction analysis mpModel->updateSimulatedValues(mReducedModel); // TO REMOVE : mpModel->applyAssignments(); // Calculate Jacobian for time step control mpModel->calculateJacobianX(mJacobian, 1e-6, 1e-12); // new entry for every entry contains the current data of currently step setVectors(slow); // set the stepcounter mCurrentStep += 1; return; }