예제 #1
0
파일: gauss.cpp 프로젝트: BertiniM2/M2
void GaussElimComputation::start_computation()
{
  if (status() == COMP_DONE) return;
  for (; row >= 0; row--)
    {
      if (gb_list[row] == NULL) continue;
      while (reduce_list[row] != NULL)
        {
          gm_elem *p = reduce_list[row];
          reduce_list[row] = p->next;
          p->next = NULL;
          reduce(gb_list[row], p);  // replaces p
          if (M2_gbTrace >= 3)
            {
              if (p->f == NULL)
                {
                  if (p->fsyz == NULL)
                    emit_wrapped("o");
                  else
                    emit_wrapped("z");
                }
              else
                emit_wrapped("r");
            }
          else
            {
            }
          insert(p);
          n_pairs++;
          if (system_interrupted())
            {
              set_status(COMP_INTERRUPTED);
              return;
            }
          if (n_pairs == stop_.pair_limit)
            {
              set_status(COMP_DONE_PAIR_LIMIT);
              return;
            }
          if (n_syz == stop_.syzygy_limit)
            {
              set_status(COMP_DONE_SYZYGY_LIMIT);
              return;
            }
        }
    }
  // Now auto reduce these
  for (int r = 1; r < gens->n_rows(); r++)
    {
      if (gb_list[r] == 0) continue;
      reduce(gb_list[r]->f, gb_list[r]->fsyz, true);
    }
  if (M2_gbTrace >= 1)
    {
      buffer o;
      text_out(o);
      emit(o.str());
    }
  set_status(COMP_DONE);
}
예제 #2
0
void GaussElimComputation::start_computation()
{
  if (status() == COMP_DONE) return;
  for ( ; row >= 0; row--)
    {
      if (gb_list[row] == NULL) continue;
      while (reduce_list[row] != NULL)
        {
          gm_elem *p = reduce_list[row];
          reduce_list[row] = p->next;
          p->next = NULL;
          reduce(gb_list[row], p); // replaces p
          if (M2_gbTrace >= 3)
            if (p->f == NULL)
              if (p->fsyz == NULL)
                emit_wrapped("o");
              else
                emit_wrapped("z");
            else
              emit_wrapped("r");
          insert(p);
          n_pairs++;
          if (test_Field(THREADLOCAL(interrupts_interruptedFlag,struct atomic_field)))
            {
              set_status(COMP_INTERRUPTED);
              return;
            }
          if (n_pairs == stop_.pair_limit)
            {
              set_status(COMP_DONE_PAIR_LIMIT);
              return;
            }
          if (n_syz == stop_.syzygy_limit)
            {
              set_status(COMP_DONE_SYZYGY_LIMIT);
              return;
            }
        }
    }
예제 #3
0
파일: gb-test1.cpp 프로젝트: pzinn/M2
bool gbB::process_spair(spair *p)
{
  stats_npairs++;

  bool not_deferred = reduceit(p);

  if (!not_deferred) return true;

  gbelem_type minlevel = (p->type == SPAIR_GEN ? ELEMB_MINGEN : 0) | ELEMB_MINGB;

  if (p->type == SPAIR_GEN) n_gens_left--;
  POLY f = p->x.f;
  p->x.f.f = 0;
  p->x.f.fsyz = 0;
  spair_delete(p);

  if (!R->gbvector_is_zero(f.f))
    {
      insert_gb(f,minlevel);
      if (M2_gbTrace == 3)      emit_wrapped("m");
    }
  else
    {
      originalR->get_quotient_info()->gbvector_normal_form(Fsyz, f.fsyz);
      if (!R->gbvector_is_zero(f.fsyz))
        {
          /* This is a syzygy */
          collect_syzygy(f.fsyz);
          if (M2_gbTrace == 3) emit_wrapped("z");
        }
      else
        {
          if (M2_gbTrace == 3) emit_wrapped("o");
        }
    }
  return true;
}
예제 #4
0
파일: det.cpp 프로젝트: AlessandroOneto/M2
int DetComputation::calc(int nsteps)
{
  for (;;)
    {
      int r = step();
      if (M2_gbTrace >= 3)
        emit_wrapped(".");
      if (r == COMP_DONE)
        return COMP_DONE;
      if (--nsteps == 0)
        return COMP_DONE_STEPS;
      if (system_interrupted())
        return COMP_INTERRUPTED;
    }
}
예제 #5
0
파일: gb-test1.cpp 프로젝트: pzinn/M2
void gbB::spair_set_defer(spair *&p)
  // Defer the spair p until later in this same degree
  // The spair should have been reduced a number of times
  // already, so its type should be SPAIR_GEN or SPAIR_ELEM
{
  if (M2_gbTrace == 15)
    {
      emit_line("    deferred by reduction count");
    }
  else if (M2_gbTrace >= 4) emit_wrapped("D");
  //  spair_delete(p); // ONLY FOR TESTING!! THIS IS INCORRECT!!
  //  return;
  S->n_in_degree++;
  if (p->type == SPAIR_GEN)
    {
      S->gen_last_deferred->next = p;
      S->gen_last_deferred = p;
    }
  else
    {
      S->spair_last_deferred->next = p;
      S->spair_last_deferred = p;
    }
}
예제 #6
0
파일: gb-test1.cpp 프로젝트: pzinn/M2
// new code
void gbB::do_computation()
{
  ComputationStatusCode ret;
  spair *p;

  // initial state is STATE_NEWDEGREE

  if (stop_.always_stop) return; // don't change status

  if ((ret = computation_is_complete()) != COMP_COMPUTING)
    {
      set_status(ret);
      return;
    }

  if (M2_gbTrace == 15)
    {
      emit_line("[gb]");
    }
  else if (M2_gbTrace >= 1)
    {
      emit_wrapped("[gb]");
    }
  for (;;)
    {
      if (stop_.stop_after_degree && this_degree > stop_.degree_limit->array[0])
        {
          // Break out now if we don't have anything else to compute in this degree.
          set_status(COMP_DONE_DEGREE_LIMIT);
          return;
        }
      if (M2_gbTrace & PrintingDegree)
        {
        }

      switch(state) {

      case STATE_NEWPAIRS:
        // Loop through all of the new GB elements, and
        // compute spairs.  Start at np_i
        // np_i is initialized at the beginning, and also here.
            while (np_i < n_gb)
              {
                if (system_interrupted())
                  {
                    set_status(COMP_INTERRUPTED);
                    return;
                  }
                if (gb[np_i]->minlevel & ELEMB_MINGB)
                  update_pairs(np_i);
                np_i++;
              }
            state = STATE_NEWDEGREE;

      case STATE_NEWDEGREE:
        // Get the spairs and generators for the next degree

            if (S->n_in_degree == 0)
              {
                int old_degree = this_degree;
                npairs = spair_set_prepare_next_degree(this_degree); // sets this_degree
                if (old_degree < this_degree)
                  first_in_degree = INTSIZE(gb);
                complete_thru_this_degree = this_degree-1;
                if (npairs == 0)
                  {
                    state = STATE_DONE;
                    set_status(COMP_DONE);
                    return;
                  }
                if (stop_.stop_after_degree && this_degree > stop_.degree_limit->array[0])
                  {
                    set_status(COMP_DONE_DEGREE_LIMIT);
                    return;
                  }
                if (hilbert)
                  {
                    if (!hilbert->setDegree(this_degree))
                      {
                        if (error())
                          set_status(COMP_ERROR);
                        else
                          set_status(COMP_INTERRUPTED);
                        return;
                      }
                  }
              }
            if (M2_gbTrace == 15)
              {
                buffer o;
                o << "DEGREE " << this_degree;
                o << ", number of spairs = " << npairs;
                if (hilbert)
                  o << ", expected number in this degree = " << hilbert->nRemainingExpected();
                emit_line(o.str());
              }
            else if (M2_gbTrace >= 1)
              {
                buffer o;
                o << '{' << this_degree << '}';
                o << '(';
                if (hilbert)
                  o << hilbert->nRemainingExpected() << ',';
                o << npairs << ')';
                emit_wrapped(o.str());
              }
            ar_i = n_gb;
            ar_j = ar_i+1;
            state = STATE_SPAIRS;

      case STATE_SPAIRS:
      case STATE_GENS:
        // Compute the spairs for this degree

            while ((p = spair_set_next()) != 0)
              {
                process_spair(p);
                npairs--;
                n_pairs_computed++;

                if ((ret = computation_is_complete()) != COMP_COMPUTING)
                  {
                    set_status(ret);
                    return;
                  }

                if (system_interrupted())
                  {
                    set_status(COMP_INTERRUPTED);
                    return;
                  }
              }
            state = STATE_AUTOREDUCE;
            // or state = STATE_NEWPAIRS

      case STATE_AUTOREDUCE:
        // This is still possibly best performed when inserting a new element
        // Perform the necessary or desired auto-reductions
        while (ar_i < n_gb)
              {
                while (ar_j < n_gb)
                  {
                    if (system_interrupted())
                      {
                        set_status(COMP_INTERRUPTED);
                        return;
                      }
                    R->gbvector_auto_reduce(F, Fsyz,
                                            gb[ar_i]->g.f, gb[ar_i]->g.fsyz,
                                            gb[ar_j]->g.f, gb[ar_j]->g.fsyz);
                    ar_j++;
                  }
                ar_i++;
                ar_j = ar_i+1;
              }
            state = STATE_NEWPAIRS;
            break;

      case STATE_DONE:
        return;
      }
  }
}
예제 #7
0
파일: gb-test1.cpp 프로젝트: pzinn/M2
void gbB::remainder(POLY &f, int degf, bool use_denom, ring_elem &denom)
  // find the remainder of f = [g,gsyz] wrt the GB,
  // i.e. replace f with h[h,hsyz], st
  //    h = f - sum(a_i * g_i),  in(f) not in in(G)
  //    hsyz = fsyz - sum(a_i * gsyz_i)
  //    denom is unchanged
  // (Here: G = (g_i) is the GB, and a_i are polynomials generated
  // during division).
  // c is an integer, and is returned as 'denom'.
  // Five issues:
  // (a) if gcd(c, coeffs(f)) becomes > 1, can we divide
  //     c, f, by this gcd? If so, how often do we do this?
  // (b) do we reduce by any element of the GB, or only those whose
  //     sugar degree is no greater than degf?
  // (c) can we exclude an element of the GB from the g_i?
  //     (for use in auto reduction).
  // (d) can we reduce by the minimal GB instead of the original GB?
  //     ANSWER: NO.  Instead, use a routine to make a new GB.
  // (e) Special handling of quotient rings: none needed.
{
  exponents EXP = ALLOCATE_EXPONENTS(exp_size);

  gbvector head;
  gbvector *frem = &head;
  frem->next = 0;
  int count = 0;
  POLY h = f;
  while (!R->gbvector_is_zero(h.f))
    {
      int gap;
      R->gbvector_get_lead_exponents(F, h.f, EXP);
      int x = h.f->comp;
      int w = find_good_divisor(EXP,x,degf,  gap);
        // replaced gap, g.
      if (w < 0 || gap > 0)
        {
          frem->next = h.f;
          frem = frem->next;
          h.f = h.f->next;
          frem->next = 0;
        }
      else
        {
          POLY g = gb[w]->g;
          R->gbvector_reduce_lead_term(F, Fsyz,
                                       head.next,
                                       h.f, h.fsyz,
                                       g.f, g.fsyz,
                                       use_denom, denom);
          count++;
          //      stats_ntail++;
          if (M2_gbTrace >= 10)
            {
              buffer o;
              o << "  tail reducing by ";
              R->gbvector_text_out(o,F,g.f, 2);
              o << "\n    giving ";
              R->gbvector_text_out(o,F,h.f, 3);
              emit_line(o.str());
            }

        }
    }
  h.f = head.next;
  R->gbvector_remove_content(h.f, h.fsyz, use_denom, denom);
  f.f = h.f;
  f.fsyz = h.fsyz;
  if ((M2_gbTrace & PRINT_SPAIR_TRACKING) != 0)
    {
      buffer o;
      o << "number of reduction steps was " << count;
      emit_line(o.str());
    }
  else if (M2_gbTrace >= 4 && M2_gbTrace != 15)
    {
      buffer o;
      o << "," << count;
      emit_wrapped(o.str());
    }
}
예제 #8
0
파일: gb-test1.cpp 프로젝트: pzinn/M2
bool gbB::reduceit(spair *p)
{
  /* Returns false iff we defer computing this spair. */
  /* If false is returned, this routine has grabbed the spair 'p'. */

  exponents EXP = ALLOCATE_EXPONENTS(exp_size);

  int tmf, wt;
  int count = -1;
  if (M2_gbTrace == 15)
    {
      buffer o;
      o << "considering ";
      spair_text_out(o,p);
      o << " : ";
      emit_line(o.str());
    }
  compute_s_pair(p); /* Changes the type, possibly */

  while (!R->gbvector_is_zero(p->f()))
    {
      if (count++ > max_reduction_count)
        {
          spair_set_defer(p);
          return false;
        }
      if (M2_gbTrace >= 5)
        {
          if ((wt = weightInfo->gbvector_weight(p->f(), tmf)) > this_degree)
            {
              buffer o;
              o << "ERROR: degree of polynomial is too high: deg " <<  wt
                << " termwt " << tmf
                << " expectedeg " << this_degree
                << newline;
              emit(o.str());
            }
        }

      int gap,w;
      R->gbvector_get_lead_exponents(F, p->f(), EXP);
      int x = p->f()->comp;
      w = find_good_divisor(EXP,x,this_degree, gap);

      // replaced gap, g.
      if (w < 0) break;
      if (false && gap > 0)
        {
          POLY h;
          h.f = R->gbvector_copy(p->x.f.f);
          h.fsyz = R->gbvector_copy(p->x.f.fsyz);
          insert_gb(h,(p->type == SPAIR_GEN ? ELEMB_MINGEN : 0));
        }
      POLY g = gb[w]->g;

      R->gbvector_reduce_lead_term(F, Fsyz,
                                   0,
                                   p->f(), p->fsyz(), /* modifies these */
                                   g.f, g.fsyz);

      stats_nreductions++;
      if (M2_gbTrace == 15)
        {
          buffer o;
          o << "    reducing by g" << w;
          o << ", yielding ";
          R->gbvector_text_out(o, F, p->f(), 3);
          emit_line(o.str());
        }
      if (R->gbvector_is_zero(p->f())) break;
      if (gap > 0)
        {
          p->deg += gap;
          if (M2_gbTrace == 15)
            {
              buffer o;
              o << "    deferring to degree " << p->deg;
              emit_line(o.str());
            }
          spair_set_insert(p);
          return false;
        }
    }
  if (M2_gbTrace >= 4 && M2_gbTrace != 15)
    {
      buffer o;
      o << "." << count;
      emit_wrapped(o.str());
    }
  return true;
}
예제 #9
0
파일: text-io.hpp 프로젝트: jeremyong/M2
inline void emit_wrapped(int prlevel, const char *s) {
    if (M2_gbTrace >= prlevel) emit_wrapped(s);
}