// subtracts p2 from p1 Polynomial *subtract_polys(Polynomial *p1, Polynomial *p2) { // just make everything in the p2 negative, then call add for (int i = 0; i < p2->num_terms; i++){ p2->terms[i].coeff.num *= -1; } return add_polys(p1, p2); }
/* gamma = product (1-z*a^Ij) for erasure locs Ij */ void CReedSolomon::init_gamma (int gamma []) { int tmp [MAX_LENGTH]; for (int i = 0; i < MAX_LENGTH; i ++) { gamma [i] = 0; tmp [i] = 0; } gamma[0] = 1; for (int e = 0; e < m_NErasures; e ++) { copy_poly (tmp, gamma); scale_poly (byExpToInt [m_ErasureLocs [e]], tmp); mul_z_poly (tmp); add_polys (gamma, tmp); } }
/* gamma = product (1-z*a^Ij) for erasure locs Ij */ void init_gamma (int gamma[]) { int e, tmp[MAXDEG]; zero_poly(gamma); zero_poly(tmp); gamma[0] = 1; for (e = 0; e < NErasures; e++) { copy_poly(tmp, gamma); scale_poly(gexp[ErasureLocs[e]], tmp); mul_z_poly(tmp); add_polys(gamma, tmp); } }
Polynomial divide_polys(Polynomial poly1, Polynomial poly2) { Polynomial tmp = copy_poly(poly1); Polynomial quotient = NULL; while (tmp) { double coeff = (double)tmp->coeff / poly2->coeff; int degree = tmp->degree - poly2->degree; if (coeff != (int)coeff || degree < 0) return NULL; Polynomial poly2_copy = copy_poly(poly2); multiply_monom_to_poly(-(int)coeff, degree, poly2_copy); Polynomial sum = add_polys(tmp, poly2_copy); free_poly(poly2_copy); free_poly(tmp); tmp = sum; add_monom_to_poly((int)coeff, degree, "ient); } free_poly(tmp); return quotient; return NULL; }
Polynomial multiply_polys(Polynomial poly1, Polynomial poly2) { Polynomial product = NULL; if (!poly1 || !poly2) return product; Monomial *current = poly2; while (current) { Polynomial poly = copy_poly(poly1); multiply_monom_to_poly(current->coeff, current->degree, poly); current = current->next_monomial; if (!product) product = copy_poly(poly); else { Polynomial sum = add_polys(product, poly); free_poly(product); product = sum; } free_poly(poly); } return product; }
// does polynomial long division, p1 divided by p2 void divide_polys(Polynomial *p1, Polynomial *p2, Polynomial **quot, Polynomial **rem) { int max = 2 * p2->num_terms; int count = 0; Polynomial *res; Polynomial *old_temp, *new_temp; Polynomial *old_div, *new_div; Polynomial **quots; // need to allocate some polynomails, let's just assume we need // double the space of the dividend and then adjust if it goes over *quot = empty_poly(p1->num_vars, 1, p1->vars); divide_terms(&p1->terms[0], &p2->terms[0], &((*quot)->terms[0]), p1->num_vars); // not divisible from the get go, so the quot is 0 // and the remainder is all of p1 if ((*quot)->terms[0].coeff.num == 0) { *rem = copy_poly(p1); return; } // the first term was not 0, so we need to set this polynomial in our list of // partial quotients. don't forget to malloc space for the list quots = (Polynomial **) malloc(sizeof(Polynomial *) * max); quots[count] = *quot; count++; // copy the divisor old_div = copy_poly(p1); while(true) { res = multiply_polys(quots[count-1], p2); // get the new dividend new_div = subtract_polys(old_div, res); sort_polynomial(new_div); free(old_div); // see if it can be divided quots[count] = empty_poly(p1->num_vars, 1, p1->vars); divide_terms(&new_div->terms[0], &p2->terms[0], "s[count]->terms[0], p1->num_vars); if (quots[count]->terms[0].coeff.num == 0) { res = new_div; break; } // it divided, time to loop again count += 1; free(res); old_div = new_div; // increase solutions array ? if (count == max-1){ quots = double_poly_array(quots, &max); } } // sum everything in the quotes list old_temp = zero_poly(p1); for (int i = 0; i < count; i++) { new_temp = add_polys(old_temp, quots[i]); free(old_temp); free(quots[i]); old_temp = new_temp; } free(quots); // set the quotient and remainder *quot = new_temp; *rem = res; }