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; }
void FractionField::degree(const ring_elem a, int *d) const { const frac_elem *f = FRAC_VAL(a); R_->degree(f->numer, d); int *e = degree_monoid()->make_one(); R_->degree(f->denom, e); degree_monoid()->divide(d, e, d); degree_monoid()->remove(e); }
bool FractionField::multi_degree(const ring_elem a, int *d) const { const frac_elem *f = FRAC_VAL(a); bool tophom = R_->multi_degree(f->numer, d); int *e = degree_monoid()->make_one(); bool bottomhom = R_->multi_degree(f->denom, e); degree_monoid()->divide(d, e, d); degree_monoid()->remove(e); return tophom && bottomhom; }
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; }
void FreeModule::append_schreyer(const int *d, const int *base, int compare_num) { assert(schreyer != 0); int *p = degree_monoid()->make_new(d); components.append(p); schreyer->append(compare_num,base); }
void FreeModule::change_degree(int i, const int *deg) { // WARNING: this modifies the degree, and should only be used during // the construction of a free module (or matrix). assert(i >= 0); assert(i < rank()); degree_monoid()->copy(deg, components[i]); }
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; }
unsigned int FreeModule::computeHashValue() const { unsigned int hashval = 13; if (degree_monoid()->n_vars() == 0) hashval += rank(); else for (int i=0; i<rank(); i++) hashval = 14535*hashval + degree(i)[0]; return hashval; }
FreeModule::FreeModule(const Ring *RR, int n, bool has_schreyer_order) // Create R^n, with all gradings zero. { initialize(RR); int *deg = degree_monoid()->make_one(); for (int i=0; i<n; i++) append(deg); degree_monoid()->remove(deg); if (has_schreyer_order) { const PolynomialRing *P = RR->cast_to_PolynomialRing(); assert(P != 0); assert(n == 0); schreyer = SchreyerOrder::create(P->getMonoid()); } else schreyer = 0; }
void FreeModule::text_out(buffer &o) const { int i; int rk = rank(); o << "free(rank " << rk << " degrees = {"; for (i=0; i<rk; i++) { if (i != 0) o << ", "; degree_monoid()->elem_text_out(o, degree(i)); } o << "}"; if (schreyer != NULL) schreyer->text_out(o); o << ')'; }
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; }
bool FreeModule::is_equal(const FreeModule *F) const { int i; if (this == F) return true; if (this->get_ring() != F->get_ring()) return false; if (rank() != F->rank()) return false; const Monoid *D = degree_monoid(); if (D->n_vars() > 0) for (i=0; i<rank(); i++) if (0 != D->compare(degree(i), F->degree(i))) return false; if (schreyer != NULL) return schreyer->is_equal(F->schreyer); if (F->schreyer != NULL) return false; return true; }
int FreeModule::primary_degree(int i) const { int result = degree_monoid()->degree_weights(degree(i),get_ring()->get_heft_vector()); return result; }
void FreeModule::append(const int *d) { assert(schreyer == 0); int *p = degree_monoid()->make_new(d); components.append(p); }