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"); } }
/** * 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"); } }