qpq_t ointer mixing for _mul and _div, fix last merge.

Former-commit-id: 4c7a5de21c8c783ae4af4781b77f8b0d3babd6e3
This commit is contained in:
Marek Nečada 2019-10-25 21:03:55 +03:00
parent 5f77fd9386
commit 0c5a38371f
2 changed files with 30 additions and 23 deletions

View File

@ -93,13 +93,14 @@ void qpq_canonicalise(qpq_t *p) {
}
void qpq_set(qpq_t *p, const qpq_t *orig) {
const int order = orig->order, offset = orig->offset;
qpq_extend(p, order - offset + 1);
for (int i = orig->offset; i <= order; ++i)
mpq_set(p->coeffs[i - offset], orig->coeffs[i - offset]);
p->offset = offset;
p->order = order;
return;
if(p != orig) {
const int order = orig->order, offset = orig->offset;
qpq_extend(p, order - offset + 1);
for (int i = orig->offset; i <= order; ++i)
mpq_set(p->coeffs[i - offset], orig->coeffs[i - offset]);
p->offset = offset;
p->order = order;
}
}
void qpq_set_elem(qpq_t *p, const int exponent, const mpq_t coeff) {
@ -240,11 +241,12 @@ void qpq_sub(qpq_t *dif, const qpq_t *x, const qpq_t *y) {
dif->order = maxorder;
}
void qpq_mul(qpq_t *p, const qpq_t *x, const qpq_t *y) {
void qpq_mul(qpq_t *p_orig, const qpq_t *x, const qpq_t *y) {
const int maxorder = x->order + y->order;
const int minoffset = x->offset + y->offset;
// Easiest way to set p to a zero polynomial...
qpq_clear(p);
qpq_t p[1];
qpq_init(p, maxorder - minoffset + 1);
mpq_t tmp; mpq_init(tmp);
for (int xi = x->offset; xi <= x->order; ++xi)
@ -252,12 +254,18 @@ void qpq_mul(qpq_t *p, const qpq_t *x, const qpq_t *y) {
mpq_mul(tmp, x->coeffs[xi - x->offset], y->coeffs[yi - y->offset]);
mpq_add(p->coeffs[xi + yi - minoffset], p->coeffs[xi + yi - minoffset], tmp);
}
mpq_clear(tmp);
p->order = maxorder;
p->offset = minoffset;
mpq_clear(tmp);
qpq_set(p_orig, p);
qpq_clear(p);
}
void qpq_div(qpq_t *q, qpq_t *r, const qpq_t *dend, const qpq_t *dor) {
void qpq_div(qpq_t *q_orig, qpq_t *r_orig, const qpq_t *dend, const qpq_t *dor) {
QPMS_ENSURE(q_orig != r_orig,
"Quotient and remainder must be _different_ instances of qpq_t.");
// Split the divisor into "head" and "tail"
qpq_t dor_tail[1]; qpq_init(dor_tail, dor->order - dor->offset); // divisor tail
qpq_set(dor_tail, dor);
@ -269,17 +277,14 @@ void qpq_div(qpq_t *q, qpq_t *r, const qpq_t *dend, const qpq_t *dor) {
mpq_set(dor_head, dor_tail->coeffs[dor_order - dor_tail->offset]);
dor_tail->order--;
qpq_zero(q);
qpq_extend(q, dend->order - dor_order + 1);
qpq_t q[1]; qpq_init(q, dend->order - dor_order + 1);
q->order = dend->order - dor_order;
q->offset = 0;
// Assign the dividend to r but with extended capacity (with zero offset)
qpq_extend(r, dend->order + 1);
qpq_t r[1]; qpq_init(r, dend->order + 1);
r->offset = 0;
r->order = dend->order;
for (int n = 0; n < dend->offset; ++n)
mpq_set_si(r->coeffs[n], 0, 1);
for (int n = dend->offset; n <= dend->order; ++n)
mpq_set(r->coeffs[n], dend->coeffs[n - dend->offset]);
@ -304,6 +309,9 @@ void qpq_div(qpq_t *q, qpq_t *r, const qpq_t *dend, const qpq_t *dor) {
qpq_canonicalise(r);
qpq_canonicalise(q);
qpq_set(q_orig, q);
qpq_set(r_orig, r);
qpq_clear(r); qpq_clear(f);
}
@ -328,7 +336,7 @@ void qpq_deriv(qpq_t *dp, const qpq_t *p) {
void qpq_legendroid_init(qpq_legendroid_t *p) {
qpq_init(&p->p);
qpq_init(&p->p, 0);
p->f = 0;
}
@ -342,11 +350,10 @@ void qpq_legendroid_mul(qpq_legendroid_t *p, const qpq_legendroid_t *a, const qp
if (a->f && b->f) {
// TODO make somehow a static representation of this constant polynomial
qpq_t ff;
qpq_init(&ff);
qpq_extend(&ff, 3);
qpq_init(&ff, 3);
qpq_set_elem_si(&ff, 0, -1, 1);
qpq_set_elem_si(&ff, 2, 1, 1);
qpq_mul(p, &ff);
qpq_mul(&p->p, &p->p, &ff);
qpq_clear(&ff);
}
p->f = !(a->f) != !(b->f);

View File

@ -57,11 +57,11 @@ void qpq_add(qpq_t *sum, const qpq_t *addend1, const qpq_t *addend2);
void qpq_sub(qpq_t *difference, const qpq_t *minuend, const qpq_t *substrahend);
/// Polynomial multiplication.
/** Does not support operand and result pointer mixing. */
/** Supports operand and result pointer mixing. */
void qpq_mul(qpq_t *product, const qpq_t *multiplier, const qpq_t *multiplicand);
/// Polynomial division with remainder.
/** Does not support operand and result pointer mixing. */
/** Supports operand and result pointer mixing. */
void qpq_div(qpq_t *quotient, qpq_t *remainder, const qpq_t *dividend, const qpq_t *divisor);
/// Polynomial derivative.