1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
// Copyright 2003 Michael E. Stillman
#include "skewpoly.hpp"
#include "gbring.hpp"
#include "skew.hpp"
SkewPolynomialRing::~SkewPolynomialRing() {}
bool SkewPolynomialRing::initialize_skew(M2_arrayint skewvars)
{
is_skew_ = true;
skew_ = SkewMultiplication(nvars_, skewvars->len, skewvars->array);
return true;
}
SkewPolynomialRing *SkewPolynomialRing::create(const Ring *K,
const Monoid *M,
M2_arrayint skewvars)
{
SkewPolynomialRing *result = new SkewPolynomialRing;
result->initialize_poly_ring(K, M);
if (!result->initialize_skew(skewvars)) return 0;
result->gb_ring_ = GBRing::create_SkewPolynomialRing(K, M, result->skew_);
return result;
}
void SkewPolynomialRing::text_out(buffer &o) const
{
o << "SkewPolynomialRing(";
K_->text_out(o);
M_->text_out(o);
o << ")";
}
static int sign4[4] = {1, 1, -1, -1};
ring_elem SkewPolynomialRing::antipode(const ring_elem f) const
{
Nterm head;
Nterm *inresult = &head;
exponents EXP = ALLOCATE_EXPONENTS(exp_size);
for (Nterm *s = f; s != NULL; s = s->next)
{
M_->to_expvector(s->monom, EXP);
int deg = skew_.skew_degree(EXP);
// sign is (-1)^ (binomial(deg,2))
// deg = 0: sign is 1
// deg = 1: sign is 1
// deg = 2: sign is -1
// deg = 3: sign is -1
// deg = 4: sign is 1, and so on
int mod4 = deg % 4;
int sign = sign4[mod4];
Nterm *t = new_term();
t->next = 0;
t->coeff = (sign == 1 ? s->coeff : K_->negate(s->coeff));
M_->copy(s->monom, t->monom);
inresult->next = t;
inresult = inresult->next;
}
inresult->next = 0;
return head.next;
}
ring_elem SkewPolynomialRing::mult_by_term(const ring_elem f,
const ring_elem c,
const int *m) const
// Computes c*m*f, BUT NOT doing normal form wrt a quotient ideal..
{
Nterm head;
Nterm *inresult = &head;
exponents EXP1 = ALLOCATE_EXPONENTS(exp_size);
exponents EXP2 = ALLOCATE_EXPONENTS(exp_size);
M_->to_expvector(m, EXP1);
for (Nterm *s = f; s != NULL; s = s->next)
{
M_->to_expvector(s->monom, EXP2);
int sign = skew_.mult_sign(EXP1, EXP2);
if (sign == 0) continue;
Nterm *t = new_term();
t->next = 0;
t->coeff = K_->mult(c, s->coeff);
if (sign < 0) K_->negate_to(t->coeff);
M_->mult(m, s->monom, t->monom);
inresult->next = t;
inresult = inresult->next;
}
inresult->next = 0;
return head.next;
}
ring_elem SkewPolynomialRing::power(const ring_elem f, mpz_srcptr n) const
{
std::pair<bool, int> n1 = RingZZ::get_si(n);
if (n1.first)
return power(f, n1.second);
else
throw exc::engine_error("exponent too large");
}
ring_elem SkewPolynomialRing::power(const ring_elem f, int n) const
{
return Ring::power(f, n);
}
// Local Variables:
// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
// indent-tabs-mode: nil
// End:
|