void toVarpower(const_schur_partition a, intarray &result) { int len = a[0]; int *result_vp = result.alloc(2*len); int *orig_result_vp = result_vp; result_vp++; if (len > 1) { int v = a[1]; int e = 1; for (int i=2; i<len; i++) { if (v == a[i]) e++; else { *result_vp++ = v; *result_vp++ = e; v = a[i]; e = 1; } } *result_vp++ = v; *result_vp++ = e; } int newlen = static_cast<int>(result_vp - orig_result_vp); *orig_result_vp = newlen; result.shrink(newlen); }
void varpower::monsyz(const int *a, const int *b, intarray &sa, intarray &sb) // sa, sb are set so that a * sa = b * sb // and sa, sb have disjoint support. { int *result_vp1 = sa.alloc(*b); int *result_vp2 = sa.alloc(*a); int *orig_result_vp1 = result_vp1; int *orig_result_vp2 = result_vp2; result_vp1++; result_vp2++; index_varpower i = a; index_varpower j = b; int va = (i.valid() ? i.var() : -1); int vb = (j.valid() ? j.var() : -1); for (;;) { if (va > vb) { // va should be placed into sb *result_vp2++ = va; *result_vp2++ = i.exponent(); ++i; va = (i.valid() ? i.var() : -1); } else if (va < vb) { // vb should be placed into sa *result_vp1++ = vb; *result_vp1++ = j.exponent(); ++j; vb = (j.valid() ? j.var() : -1); } else { if (va == -1) break; int ea = i.exponent(); int eb = j.exponent(); if (ea < eb) { *result_vp1++ = va; *result_vp1++ = eb-ea; } else if (ea > eb) { *result_vp2++ = va; *result_vp2++ = ea-eb; } ++i; ++j; va = (i.valid() ? i.var() : -1); vb = (j.valid() ? j.var() : -1); } } *orig_result_vp1 = static_cast<int>(result_vp1 - orig_result_vp1); *orig_result_vp2 = static_cast<int>(result_vp2 - orig_result_vp2); }
void varpower::mult(const int *a, const int *b, intarray &result) { int len = *a + *b; // potential length int *result_vp = result.alloc(len); int *orig_result_vp = result_vp; result_vp++; index_varpower i = a; index_varpower j = b; // merge the two varpowers to staticVP int va = (i.valid() ? i.var() : -1); int vb = (j.valid() ? j.var() : -1); for (;;) { if (va > vb) { *result_vp++ = va; *result_vp++ = i.exponent(); ++i; va = (i.valid() ? i.var() : -1); } else if (vb > va) { *result_vp++ = vb; *result_vp++ = j.exponent(); ++j; vb = (j.valid() ? j.var() : -1); } else { if (va == -1) break; int x = i.exponent(); int y = j.exponent(); int z = x+y; if ((x < 0) == (y < 0) && (x < 0) != (z < 0)) { ERROR("monomial overflow"); } else { if (z != 0) { *result_vp++ = va; *result_vp++ = z; } } ++i; ++j; va = (i.valid() ? i.var() : -1); vb = (j.valid() ? j.var() : -1); } } int newlen = static_cast<int>(result_vp - orig_result_vp); *orig_result_vp = newlen; result.shrink(newlen); }
void varpower::radical(const int *a, intarray &result) { // length of result is the same as that of a int *result_vp = result.alloc(*a); *result_vp++ = *a; for (index_varpower i = a; i.valid(); ++i) { *result_vp++ = i.var(); // var *result_vp++ = 1; // exponent } }
void varpower::power(const int *a, int n, intarray &result) { if (n == 0) { result.append(1); return; } int *result_vp = result.alloc(*a); *result_vp++ = *a; for (index_varpower i = a; i.valid(); ++i) { *result_vp++ = i.var(); *result_vp++ = safe::mult(i.exponent(),n); } }
void varpower::from_ntuple(int n, const int *a, intarray &result) { int len = 0; for (int i=0; i<n; i++) if (a[i] != 0) len++; int result_len = 2*len + 1; int *result_vp = result.alloc(result_len); *result_vp++ = result_len; for (int i=n-1; i>=0; i--) if (a[i] != 0) { *result_vp++ = i; *result_vp++ = a[i]; } }
void varpower::from_arrayint(M2_arrayint m, intarray &result) { int *result_vp = result.alloc(m->len+1); *result_vp++ = m->len+1; int *melems = m->array; for (int i=0; i<m->len; i+=2) { int v = *melems++; int e = *melems++; check_var(v,e); *result_vp++ = v; *result_vp++ = e; } }
void varpower::lcm(const int *a, const int *b, intarray &result) { int len = *a + *b; // potential length int *result_vp = result.alloc(len); int *orig_result_vp = result_vp; result_vp++; index_varpower i = a; index_varpower j = b; // merge the two varpowers to staticVP int va = (i.valid() ? i.var() : -1); int vb = (j.valid() ? j.var() : -1); for (;;) { if (va > vb) { *result_vp++ = va; *result_vp++ = i.exponent(); ++i; va = (i.valid() ? i.var() : -1); } else if (vb > va) { *result_vp++ = vb; *result_vp++ = j.exponent(); ++j; vb = (j.valid() ? j.var() : -1); } else { if (va == -1) break; int ea = i.exponent(); int eb = j.exponent(); if (ea < eb) ea = eb; *result_vp++ = va; *result_vp++ = ea; ++i; ++j; va = (i.valid() ? i.var() : -1); vb = (j.valid() ? j.var() : -1); } } *orig_result_vp = static_cast<int>(result_vp - orig_result_vp); }
void varpower::quotient(const int *a, const int *b, intarray &result) // return a:b { int *result_vp = result.alloc(*a); int *orig_result_vp = result_vp; result_vp++; index_varpower i = a; index_varpower j = b; int va = (i.valid() ? i.var() : -1); int vb = (j.valid() ? j.var() : -1); for (;;) { if (va > vb) { *result_vp++ = va; *result_vp++ = i.exponent(); ++i; va = (i.valid() ? i.var() : -1); } else if (vb > va) { ++j; vb = (j.valid() ? j.var() : -1); } else { if (va == -1) break; int ea = i.exponent(); int eb = j.exponent(); if (ea > eb) { *result_vp++ = va; *result_vp++ = ea - eb; // overflow cannot occur } ++i; ++j; va = (i.valid() ? i.var() : -1); vb = (j.valid() ? j.var() : -1); } } *orig_result_vp = static_cast<int>(result_vp - orig_result_vp); }
void varpower::erase(const int *a, const int *b, intarray &result) // divide a by b^infinity { int *result_vp = result.alloc(*a); int *orig_result_vp = result_vp; result_vp++; index_varpower i = a; index_varpower j = b; int va = (i.valid() ? i.var() : -1); int vb = (j.valid() ? j.var() : -1); for (;;) { if (va > vb) { *result_vp++ = va; *result_vp++ = i.exponent(); ++i; va = (i.valid() ? i.var() : -1); } else if (vb > va) { ++j; vb = (j.valid() ? j.var() : -1); } else { if (va == -1) break; ++i; ++j; va = (i.valid() ? i.var() : -1); vb = (j.valid() ? j.var() : -1); } } *orig_result_vp = static_cast<int>(result_vp - orig_result_vp); }