FreeModule* ResF4toM2Interface::to_M2_freemodule(const PolynomialRing* R, SchreyerFrame& C, int lev) { FreeModule* result = new FreeModule(R, 0, true); if (lev < 0 or lev > C.maxLevel()) { return result; } const Monoid* M = R->getMonoid(); auto& thislevel = C.level(lev); const ResSchreyerOrder& S = C.schreyerOrder(lev); res_ntuple_word* longexp = new res_ntuple_word[M->n_vars()]; int* exp = new int[M->n_vars()]; for (auto i = 0; i < thislevel.size(); ++i) { int d[1]; d[0] = thislevel[i].mDegree; monomial deg = M->degree_monoid()->make_one(); M->degree_monoid()->from_expvector(d, deg); // Now grab the Schreyer info // unpack to exponent vector, then repack into monoid element monomial totalmonom = M->make_one(); long comp; C.monoid().to_exponent_vector(S.mTotalMonom[i], longexp, comp); for (int j=0; j<M->n_vars(); ++j) exp[j] = static_cast<int>(longexp[j]); M->from_expvector(exp, totalmonom); result->append_schreyer(deg, totalmonom, static_cast<int>(S.mTieBreaker[i])); } delete [] longexp; delete [] exp; return result; }
FreeModule *FreeModule::make_schreyer(const GBMatrix *m) { const FreeModule *F = m->get_free_module(); const PolynomialRing *R = F->get_ring()->cast_to_PolynomialRing(); if (R == 0) { ERROR("expected a polynomial ring"); return nullptr; } FreeModule *G = R->make_FreeModule(); int rk = INTSIZE(m->elems); if (rk == 0) return G; for (int i=0; i<rk; i++) { int *deg = R->degree_monoid()->make_one(); gbvector * v = m->elems[i]; if (v != 0) R->get_gb_ring()->gbvector_multidegree(F, v, deg); G->append(deg); } G->schreyer = SchreyerOrder::create(m); return G; }
FreeModule *FreeModule::exterior(int pp) const // p th exterior power { FreeModule *result; if (pp == 0) return get_ring()->make_FreeModule(1); else result = new_free(); int rk = rank(); if (pp > rk || pp < 0) return result; size_t p = static_cast<size_t>(pp); Subset a(p, 0); for (size_t i=0; i<p; i++) a[i] = i; int *deg = degree_monoid()->make_one(); do { degree_monoid()->one(deg); for (size_t r=0; r<p; r++) degree_monoid()->mult(deg, degree(static_cast<int>(a[r])), deg); result->append(deg); } while (Subsets::increment(rk, a)); degree_monoid()->remove(deg); if (schreyer != NULL) result->schreyer = schreyer->exterior(pp); return result; }
FreeModule *FreeModule::transpose() const { FreeModule *result = new_free(); int *deg = degree_monoid()->make_one(); for (int i=0; i<rank(); i++) { degree_monoid()->power(degree(i), -1, deg); result->append(deg); } // result has no schreyer order degree_monoid()->remove(deg); return result; }
FreeModule *FreeModule::sub_space(int n) const { if (n < 0 || n > rank()) { ERROR("subfreemodule: index out of bounds"); return NULL; } FreeModule *result = new_free(); for (int i=0; i<n; i++) result->append(degree(i)); if (schreyer != NULL) result->schreyer = schreyer->sub_space(n); return result; }
FreeModule *FreeModule::make_schreyer(const Matrix *m) { int i; const Ring *R = m->get_ring(); FreeModule *F = R->make_FreeModule(); int rk = m->n_cols(); if (rk == 0) return F; for (i=0; i<rk; i++) F->append(m->cols()->degree(i)); F->schreyer = SchreyerOrder::create(m); return F; }
FreeModule *FreeModule::sub_space(M2_arrayint a) const { FreeModule *result = new_free(); for (unsigned int i=0; i<a->len; i++) if (a->array[i] >= 0 && a->array[i] < rank()) result->append(degree(a->array[i])); else { ERROR("subfreemodule: index out of bounds"); deleteitem(result); return NULL; } if (schreyer != NULL) result->schreyer = schreyer->sub_space(a); return result; }
FreeModule *FreeModule::shift(const int *d) const // Shift degree by d. { FreeModule *result = new_free(); int *deg = degree_monoid()->make_one(); for (int i=0; i<rank(); i++) { degree_monoid()->mult(degree(i), d, deg); result->append(deg); } if (schreyer != NULL) result->schreyer = schreyer->copy(); degree_monoid()->remove(deg); return result; }
void symm1(int lastn, // can use lastn..rank()-1 in product int pow) const // remaining power to take { if (pow == 0) symm1_result->append(symm1_deg); else { for (int i=lastn; i<F->rank(); i++) { // increase symm1_deg, with e_i D->mult(symm1_deg, F->degree(i), symm1_deg); symm1(i, pow-1); // decrease symm1_deg back D->divide(symm1_deg, F->degree(i), symm1_deg); } } }
FreeModule *FreeModule::make_schreyer(const Matrix *m) { int i; const PolynomialRing *R = m->get_ring()->cast_to_PolynomialRing(); if (R == 0) { ERROR("expected a polynomial ring"); return nullptr; } FreeModule *F = R->make_FreeModule(); int rk = m->n_cols(); if (rk == 0) return F; for (i=0; i<rk; i++) F->append(m->cols()->degree(i)); F->schreyer = SchreyerOrder::create(m); return F; }
FreeModule *FreeModule::direct_sum(const FreeModule *G) const // direct sum { int i; if (get_ring() != G->get_ring()) { ERROR("expected free modules over the same ring"); return 0; } FreeModule *result = new_free(); for (i=0; i<rank(); i++) result->append(degree(i)); for (i=0; i<G->rank(); i++) result->append(G->degree(i)); // if (schreyer != NULL && G->schreyer != NULL) // result->schreyer = schreyer->direct_sum(G->schreyer); return result; }
FreeModule *value() { if (symm1_result == 0) { symm1_result = F->get_ring()->make_FreeModule(); if (n >= 0) { symm1_deg = D->make_one(); symm1(0, n); D->remove(symm1_deg); } } return symm1_result; }
FreeModule *FreeModule::tensor(const FreeModule *G) const // tensor product { if (get_ring() != G->get_ring()) { ERROR("expected free modules over the same ring"); return 0; } FreeModule *result = new_free(); int *deg = degree_monoid()->make_one(); for (int i=0; i<rank(); i++) for (int j=0; j<G->rank(); j++) { degree_monoid()->mult(degree(i), G->degree(j), deg); result->append(deg); } degree_monoid()->remove(deg); if (schreyer != NULL && G->schreyer != NULL) result->schreyer = schreyer->tensor(G->schreyer); return result; }
FreeModule *FreeModule::exterior(int p) const // p th exterior power { FreeModule *result; int rk = rank(); if (p == 0) return get_ring()->make_FreeModule(1); else result = new_free(); if (p > rk || p < 0) return result; int *a = newarray_atomic(int,p); for (int i=0; i<p; i++) a[i] = i; int *deg = degree_monoid()->make_one(); do { degree_monoid()->one(deg); for (int r=0; r<p; r++) degree_monoid()->mult(deg, degree(a[r]), deg); result->append(deg); } while (comb::increment(p, rk, a)); degree_monoid()->remove(deg); deletearray(a); if (schreyer != NULL) result->schreyer = schreyer->exterior(p); return result; }
void gbres_comp::setup(const Matrix *m, int length, int origsyz, int strategy) { int i; originalR = m->get_ring()->cast_to_PolynomialRing(); if (originalR == NULL) assert(0); GR = originalR->get_gb_ring(); mi_stash = new stash("res mi nodes", sizeof(Nmi_node)); FreeModule *Fsyz = originalR->make_Schreyer_FreeModule(); if (length <= 0) { ERROR("resolution length must be at least 1"); length = 1; } // If origsyz, and length>1, create Fsyz as a Schreyer free // if origsyz is smaller, truncate this module... if (length > 1 && origsyz > 0) { if (origsyz > m->n_cols()) origsyz = m->n_cols(); int *one = originalR->getMonoid()->make_one(); const int *mon; for (i=0; i<origsyz; i++) { if ((*m)[i] == NULL) mon = one; else { Nterm *t = (*m)[i]->coeff; mon = t->monom; } Fsyz->append_schreyer(m->cols()->degree(i), mon, i); } originalR->getMonoid()->remove(one); } lo_degree = m->cols()->lowest_primary_degree(); last_completed_degree = lo_degree-1; n_nodes = length + 1; nodes = newarray(gb_node_ptr,n_nodes); nodes[0] = new gb_emitter(m); nodes[1] = new gb2_comp(Fsyz,mi_stash,nodes[0],lo_degree,origsyz,1,strategy); nodes[0]->set_output(nodes[1]); if (n_nodes == 2) { // Don't compute syzygies at all. nodes[1]->set_output(NULL); } else if (n_nodes >= 3) { // Compute a resolution to length 'length', with last being // a gb node. int deg = lo_degree+1; if (origsyz > 0) deg--; for (i=2; i<n_nodes-1; i++) { FreeModule *F = originalR->make_Schreyer_FreeModule(); nodes[i] = new gb2_comp(F,mi_stash,nodes[i-1],deg++,-1,i,strategy); nodes[i-1]->set_output(nodes[i]); } FreeModule *F = originalR->make_Schreyer_FreeModule(); nodes[n_nodes-1] = new gb2_comp(F,mi_stash,nodes[n_nodes-2],deg++,0,n_nodes-1,strategy); nodes[n_nodes-1]->set_output(NULL); } strategy_flags = strategy; }