예제 #1
0
void polynomial_print(const Polynomial* polynomial, int newline) {
  assert(polynomial != NULL);

  printf("(");
  Monomial *current = polynomial->first;
  while(current != NULL) {
    monomial_print(current);
    current = monomial_get_next(current);
    if(current != NULL) {
      printf(", ");
    }
  }

  printf(")");

  if(newline) {
    printf("\n");
  }
}
예제 #2
0
파일: gcd.c 프로젝트: SRI-CSL/libpoly
/**
 * Extracts the largest monomial power out of P and Q and into gcd, also divide.
 * For example, P and Q in Z[y, x]
 *
 *  P = 4*y*x^2 + 2*y^2 = 2*y^2*(2*x^2 + 1)
 *  Q = 2*y^3*x^3
 *
 * gives
 *
 *  gcd = 2*y^2
 *  P = 2*x^2 + 1
 *  Q = 2*y*x^3
 */
void coefficient_gcd_monomial_extract(const lp_polynomial_context_t* ctx, coefficient_t* gcd, coefficient_t* P, coefficient_t* Q) {

  TRACE("coefficient", "coefficient_gcd_monomial_extract()\n");

  if (trace_is_enabled("coefficient")) {
    tracef("P = "); coefficient_print(ctx, P, trace_out); tracef("\n");
    tracef("Q = "); coefficient_print(ctx, Q, trace_out); tracef("\n");
  }

  assert(P != Q);

  lp_monomial_t m_P_gcd, m_Q_gcd, m_tmp;
  lp_monomial_construct(ctx, &m_P_gcd);
  lp_monomial_construct(ctx, &m_Q_gcd);
  lp_monomial_construct(ctx, &m_tmp);

  // Compute the gcd
  coefficient_traverse(ctx, P, monomial_gcd_visit, &m_tmp, &m_P_gcd);
  lp_monomial_clear(ctx, &m_tmp);
  coefficient_traverse(ctx, Q, monomial_gcd_visit, &m_tmp, &m_Q_gcd);

  if (trace_is_enabled("coefficient")) {
    tracef("P_gcd = "); monomial_print(ctx, &m_P_gcd, trace_out); tracef("\n");
    tracef("Q_gcd = "); monomial_print(ctx, &m_Q_gcd, trace_out); tracef("\n");
  }

  // Final gcd
  lp_monomial_t m_gcd;
  lp_monomial_construct(ctx, &m_gcd);
  lp_monomial_gcd(ctx, &m_gcd, &m_P_gcd, &m_Q_gcd);

  // Construct the result
  coefficient_t result;
  coefficient_construct(ctx, &result);
  coefficient_add_ordered_monomial(ctx, &m_gcd, &result);

  // Divide P and Q with their gcds
  coefficient_t P_gcd, Q_gcd;
  coefficient_construct(ctx, &P_gcd);
  coefficient_construct(ctx, &Q_gcd);
  coefficient_add_ordered_monomial(ctx, &m_P_gcd, &P_gcd);
  coefficient_add_ordered_monomial(ctx, &m_Q_gcd, &Q_gcd);
  coefficient_div(ctx, P, P, &P_gcd);
  coefficient_div(ctx, Q, Q, &Q_gcd);
  coefficient_destruct(&P_gcd);
  coefficient_destruct(&Q_gcd);

  // Output the result
  coefficient_swap(&result, gcd);
  coefficient_destruct(&result);

  lp_monomial_destruct(&m_gcd);
  lp_monomial_destruct(&m_tmp);
  lp_monomial_destruct(&m_Q_gcd);
  lp_monomial_destruct(&m_P_gcd);

  if (trace_is_enabled("coefficient")) {
    tracef("coefficient_gcd_monomial_extract() =>"); coefficient_print(ctx, gcd, trace_out); tracef("\n");
    tracef("P = "); coefficient_print(ctx, P, trace_out); tracef("\n");
    tracef("Q = "); coefficient_print(ctx, Q, trace_out); tracef("\n");
  }
}