File: skewpoly.cpp

package info (click to toggle)
macaulay2 1.21%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 133,096 kB
  • sloc: cpp: 110,377; ansic: 16,306; javascript: 4,193; makefile: 3,821; sh: 3,580; lisp: 764; yacc: 590; xml: 177; python: 140; perl: 114; lex: 65; awk: 3
file content (115 lines) | stat: -rw-r--r-- 3,054 bytes parent folder | download | duplicates (2)
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: