Exemplo n.º 1
0
int hilb_comp::calc(int n_steps)
     // Possible return values: COMP_DONE, COMP_INTERRUPTED.
{
  if (n_components == 0)
    return COMP_DONE;
  if (n_steps >= 0)
    {
      int calc_nsteps = nsteps + n_steps;
      while (calc_nsteps-- > 0)
        {
          int result = step();
          if (result == COMP_DONE)
            return COMP_DONE;
          if (system_interrupted())
            return COMP_INTERRUPTED;
        }
      return COMP_DONE_STEPS;
    }
  else for (;;)
    {
      int result = step();
      if (result == COMP_DONE)
        return COMP_DONE;
      if (system_interrupted())
        return COMP_INTERRUPTED;
    }
}
Exemplo n.º 2
0
enum ComputationStatusCode gb_emitter::calc_gb(int degree)
{
  // This is when we ship off the elements in this degree.  This should NEVER
  // be called if elements of lower degree have not been sent.
  if (this_degree != degree)
    {
      start_degree(degree);
    }
  for (;;)
    {
        if (system_interrupted())
          return COMP_INTERRUPTED;
      if (n_i >= n_gens) return COMP_DONE;
      if (g != NULL)
        {
          ring_elem denom;
          gbvector *v = originalR->translate_gbvector_from_vec(gens->rows(),
                                              (*gens)[these[n_i]],
                                              denom);
          g->receive_generator(v, these[n_i], denom);
        }
      n_i++;
      n_left--;
    }
}
Exemplo n.º 3
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");
            }
          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);
}
Exemplo n.º 4
0
int PfaffianComputation::calc(int nsteps)
{
  for (;;)
    {
      int result = step();
      if (result == COMP_DONE)
        return COMP_DONE;
      if (--nsteps == 0)
        return COMP_DONE_STEPS;
      if (system_interrupted())
        return COMP_INTERRUPTED;
    }
}
Exemplo n.º 5
0
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;
    }
}
Exemplo n.º 6
0
void binomialGB_comp::start_computation()
{
  binomial_s_pair s;
  int *deg = 0;
  if (stop_.always_stop) return; // don't change status
  if (stop_.stop_after_degree) deg = &stop_.degree_limit->array[0];
  while (Pairs->next(deg, s, top_degree))
    {
      ComputationStatusCode ret = gb_done();
      if (ret != COMP_COMPUTING) return;
      process_pair(s);          // consumes 's'.
      if (system_interrupted())
        {
          set_status(COMP_INTERRUPTED);
          return;
        }
    }
  if (Pairs->n_elems() == 0)
    set_status(COMP_DONE);
  else
    set_status(COMP_DONE_DEGREE_LIMIT);
}
Exemplo n.º 7
0
bool GF::initialize_GF(const RingElement *prim)
{
  // set the GF ring tables.  Returns false if there is an error.
  _primitive_element = prim;
  _originalR = prim->get_ring()->cast_to_PolynomialRing();
  initialize_ring(_originalR->charac(),
                  PolyRing::get_trivial_poly_ring());

  declare_field();

  int i,j;

  if (_originalR->n_quotients() != 1)
    {
      ERROR("rawGaloisField expected an element of a quotient ring of the form ZZ/p[x]/(f)");
      return false;
    }
  ring_elem f = _originalR->quotient_element(0);
  Nterm *t = f;
  int n = _originalR->getMonoid()->primary_degree(t->monom);

  Q_ = P;
  for (i=1; i<n; i++) Q_ *= P;

  Qexp_ = n;
  Q1_ = Q_-1;
  _ZERO = 0;
  _ONE = Q1_;
  _MINUS_ONE = (P == 2 ? _ONE : Q1_/2);

  // Get ready to create the 'one_table'
  array<ring_elem> polys;
  polys.append(_originalR->from_int(0));
  ring_elem primelem = prim->get_value();
  polys.append(_originalR->copy(primelem));

  ring_elem oneR = _originalR->one();

  _x_exponent = -1;
  ring_elem x = _originalR->var(0);
  if (_originalR->is_equal(primelem, x))
    _x_exponent = 1;
  for (i=2; i<Q_; i++)
    {
      ring_elem g = _originalR->mult(polys[i-1], primelem);
      polys.append(g);
      if (_originalR->is_equal(g, oneR)) break;
      if (_originalR->is_equal(g, x))
        _x_exponent = i;
    }

  if (polys.length() != Q_)
    {
      ERROR("GF: primitive element expected");
      return false;
    }

  assert(_x_exponent >= 0);

  // Set 'one_table'.
  _one_table = newarray_atomic(int,Q_);
  _one_table[0] = Q_-1;
  for (i=1; i<=Q_-1; i++)
    {
      if (system_interrupted())
        return false;
      ring_elem f1 = _originalR->add(polys[i], oneR);
      for (j=1; j<=Q_-1; j++)
        if (_originalR->is_equal(f1, polys[j]))
          break;
      _one_table[i] = j;
    }

  // Create the Z/P ---> GF(Q) inclusion map
  _from_int_table = newarray_atomic(int,P);
  int a = _ONE;
  _from_int_table[0] = _ZERO;
  for (i=1; i<P; i++)
    {
      _from_int_table[i] = a;
      a = _one_table[a];
    }

  zeroV = from_int(0);
  oneV = from_int(1);
  minus_oneV = from_int(-1);

  // M2::GaloisFieldTable G(*_originalR, primelem);
  //  G.display(std::cout);

  return true;
}
Exemplo n.º 8
0
  GaloisFieldTable::GaloisFieldTable(const PolynomialRing& R,
                                     const ring_elem prim):
    mCharac(static_cast<int>(R.characteristic())),
    mOriginalRing(R),
    mPrimitiveElement(prim)
  {
    M2_ASSERT(mOriginalRing.n_quotients() == 1);

    mGenerator = RingElement::make_raw(&R, R.copy(prim));
    ring_elem f = mOriginalRing.quotient_element(0);
    Nterm *t = f;
    mDimension = mOriginalRing.getMonoid()->primary_degree(t->monom);
    mOrder = mCharac;
    for (int i=1; i<mDimension; i++) mOrder *= mCharac;
    mOne = mOrder - 1; // representation for the number 1: p^n - 1.
    mOrderMinusOne = mOne; // p^n - 1
    mMinusOne = (mCharac == 2 ? mOne : mOne/2);
    
    // Get ready to create mOneTable.
    std::vector<ring_elem> polys;
    polys.push_back(mOriginalRing.from_long(0));
    polys.push_back(mOriginalRing.copy(mPrimitiveElement));
    
    ring_elem oneR = mOriginalRing.from_long(1);
    
    mGeneratorExponent = static_cast<GFElement>(-1);
    ring_elem x = mOriginalRing.var(0);
    if (mOriginalRing.is_equal(mPrimitiveElement, x))
      mGeneratorExponent = 1;
    for (GFElement i=2; i<=mOne; i++)
      {
	ring_elem g = mOriginalRing.mult(polys[i-1], mPrimitiveElement);
	polys.push_back(g);
	if (mOriginalRing.is_equal(g, oneR)) break;
	if (mOriginalRing.is_equal(g, x))
	  mGeneratorExponent = i;
      }

#if 0
    for (size_t i = 0; i < polys.size(); i++)
      {
        std::cerr << i << "  ";
        dringelem(&R, polys[i]);
        std::cerr << "\n";
      }
#endif
    M2_ASSERT(polys.size() == mOrder);
    M2_ASSERT(mGeneratorExponent != static_cast<GFElement>(-1));
    
    // Set 'one_table'.
    mOneTable = newarray_atomic(GFElement,mOrder);
    mOneTable[0] = mOrderMinusOne;

    for (GFElement i=1; i<=mOrderMinusOne; i++)
      {
          if (system_interrupted()) 
          {
            // first clean up?
            return;
          }
	ring_elem f1 = mOriginalRing.add(polys[i], oneR);
    GFElement j;
	for (j=0; j<=mOrderMinusOne; j++)
          if (mOriginalRing.is_equal(f1, polys[j]))
            break;
        if (j > mOrderMinusOne)
          {
            std::cout << "oops: didn't find element " << i << " !!" << std::endl;
          }
        mOneTable[i] = j;
      }
    
    // Create the ZZ/P ---> GF(Q) inclusion map
    mFromIntTable = newarray_atomic(GFElement,mCharac);
    GFElement a = mOne;;
    mFromIntTable[0] = 0;
    for (GFElement i=1; i<mCharac; i++)
      {
        mFromIntTable[i] = a;
        a = mOneTable[a];
      }
  }
Exemplo n.º 9
0
int LLLoperations::doLLL(MutableMatrix *A,
                         MutableMatrix *Achange,
                         MutableMatrix *LLLstate,
                         int nsteps)
{
  int n = A->n_cols();
  if (n == 0) return COMP_DONE;

  // Extract the state from LLLstate:
  int k, kmax;
  ring_elem a, alphaTop, alphaBottom;
  buffer o;

  if (LLLstate->get_entry(0,n,a))
    k = globalZZ->coerce_to_int(a);
  else
    k = 0;

  if (LLLstate->get_entry(0,n+1,a))
    kmax = globalZZ->coerce_to_int(a);
  else
    kmax = 0;

  LLLstate->get_entry(0,n+2,alphaTop);  // Don't free alphaTop!
  LLLstate->get_entry(0,n+3,alphaBottom);

  while (k < n && nsteps != 0 && !system_interrupted())
    {
      if (M2_gbTrace >= 1)
        {
          o.reset();
          o << ".";
          if (M2_gbTrace >= 2)
            o << k;
          if (nsteps % 20 == 0)
            o << newline;
          emit(o.str());
        }
      nsteps--;

      if (k > kmax)
        {
          if (M2_gbTrace == 1)
            {
              o.reset();
              o << "." << k;
              if (nsteps % 20 == 0)
                o << newline;
              emit(o.str());
            }

          kmax = k;
          for (int j=0; j<=k; j++)
            {
              ring_elem u;
              A->dot_product(k,j,u);
              for (int i=0; i<=j-1; i++)
                {
                  // u = (D#i * u - lambda#(k,i) * lambda#(j,i)) // D#(i-1)
                  ring_elem Di, mki, mji, Di1;
                  LLLstate->get_entry(i,i,Di);
                  globalZZ->mult_to(u, Di);
                  if (LLLstate->get_entry(i,k,mki) &&  LLLstate->get_entry(i,j,mji))
                    {
                      ring_elem t1 = globalZZ->mult(mki,mji);
                      globalZZ->subtract_to(u,t1);
                    }
                  if (i > 0)
                    {
                      LLLstate->get_entry(i-1,i-1,Di1);  // Cannot be zero!!
                      ring_elem t1 = globalZZ->divide(u,Di1);
                      globalZZ->remove(u);
                      u = t1;
                    }
                }
              // At this point we have our element:
              LLLstate->set_entry(j,k,u);
              if (j == k && globalZZ->is_zero(u))
                {
                  ERROR("LLL vectors not independent");
                  return COMP_ERROR;
                }
            }
        } // end of the k>kmax initialization
      REDI(k,k-1,A,Achange,LLLstate);
      if (Lovasz(LLLstate,k,alphaTop,alphaBottom))
        {
          SWAPI(k,kmax,A,Achange,LLLstate);
          k--;
          if (k == 0) k = 1;
        }
      else
        {
          for (int ell=k-2; ell>=0; ell--)
            REDI(k,ell,A,Achange,LLLstate);
          k++;
        }
    }

  // Before returning, reset k,kmax:
  LLLstate->set_entry(0,n,globalZZ->from_int(k));
  LLLstate->set_entry(0,n+1,globalZZ->from_int(kmax));

  if (k >= n) return COMP_DONE;
  if (nsteps == 0) return COMP_DONE_STEPS;
  return COMP_INTERRUPTED;
}
Exemplo n.º 10
0
// 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;
      }
  }
}
Exemplo n.º 11
0
Arquivo: f4.cpp Projeto: pzinn/M2
enum ComputationStatusCode F4GB::start_computation(StopConditions &stop_)
{
  clock_sort_columns = 0;
  clock_gauss = 0;
  clock_make_matrix = 0;
  int npairs;

  //  test_spair_code();

  enum ComputationStatusCode is_done = COMP_COMPUTING;

  reset_master_syz();

  for (;;)
    {
      if (system_interrupted())
        {
          is_done = COMP_INTERRUPTED;
          break;
        }

      is_done = computation_is_complete(stop_);
      if (is_done != COMP_COMPUTING) break;

      this_degree = S->prepare_next_degree(-1, npairs);

      if (npairs == 0)
        {
          is_done = COMP_DONE;
          break;
        }
      if (stop_.stop_after_degree && this_degree > stop_.degree_limit->array[0])
        {
          is_done = COMP_DONE_DEGREE_LIMIT;
          break;
        }

      if (hilbert)
        {
          if (!hilbert->setDegree(this_degree))
            {
              if (error())
                is_done = COMP_ERROR;
              else
                is_done = COMP_INTERRUPTED;
              break;
            }
        }

      if (M2_gbTrace >= 1)
        {
          if (hilbert)
            fprintf(stderr, "DEGREE %d (nexpected %d npairs %d)\n", this_degree, hilbert->nRemainingExpected(), npairs);
          else
            fprintf(stderr, "DEGREE %d (npairs %d)\n", this_degree, npairs);
        }
      do_spairs();
      complete_thru_this_degree = this_degree;
    }

  clear_master_syz();

  if (M2_gbTrace>=2)
    {
      fprintf(stderr, "number of calls to cancel row       : %ld\n", KK->n_dense_row_cancel);
      fprintf(stderr, "number of calls to subtract_multiple: %ld\n", KK->n_subtract_multiple);
      fprintf(stderr, "total time for sorting columns: %f\n", clock_sort_columns);
      if (using_syz)
        fprintf(stderr, "total time for sorting syz columns: %f\n", syz_clock_sort_columns);
      fprintf(stderr, "total time for making matrix (includes sort): %f\n", ((double)clock_make_matrix)/CLOCKS_PER_SEC);
      fprintf(stderr, "total time for gauss: %f\n", ((double)clock_gauss)/CLOCKS_PER_SEC);
      fprintf(stderr, "number of spairs computed           : %ld\n", n_pairs_computed);
      fprintf(stderr, "number of reduction steps           : %ld\n", n_reduction_steps);
    }

  fprintf(stderr, "number of spairs removed by criterion = %ld\n", S->n_unneeded_pairs());
  M->show();
  return is_done;
}