Polynomial getDerivative(Polynomial const *polynomial) { assert(polynomial->deg >= 0); Polynomial derivative; if (polynomial->deg == 0) { initPolynomial(&derivative, 0); derivative.coeffs[0] = 0.0; return derivative; } initPolynomial(&derivative, polynomial->deg - 1); for (int i = 1; i <= polynomial->deg; ++i) { derivative.coeffs[i - 1] = i * polynomial->coeffs[i]; } return derivative; }
void reportMaxError() { size_t const numof_tests = 5000; size_t const max_numof_xs = 400; size_t const numof_avg_iters = no_random ? 1 : 50; printf("\nMax error for function g(x) = %s (on [%Lf, %Lf]) and various number (#) of interpolation points:\n", g_strrep, min_x, max_x); printf(" # | error (avg among %4zu)\n", numof_avg_iters); printf("-----+-----------------------\n"); Polynomial best_polynomial; initPolynomial(&best_polynomial, DISPOSED_POLYNOMIAL_DEG); double best_error = LDBL_MAX; for (size_t numof_xs_step = 1; numof_xs_step <= 100; numof_xs_step *= 10) { Polynomial curr_polynomial; initPolynomial(&curr_polynomial, DISPOSED_POLYNOMIAL_DEG); size_t curr_numof_xs = numof_xs_step; for (size_t i = 0; i < 9 && curr_numof_xs <= max_numof_xs; ++i) { long double error = 0.0; for (size_t k = 0; k < numof_avg_iters; ++k) { long double curr_error = calcMaxError(my_g, &curr_polynomial, curr_numof_xs, numof_tests, min_x, max_x); if (fabsl(best_error) > fabsl(curr_error)) { best_error = curr_error; disposePolynomial(&best_polynomial); best_polynomial = curr_polynomial; } else { disposePolynomial(&curr_polynomial); } error += curr_error; } error /= numof_avg_iters; printf("%4zu | %-+22.4Lg\n", curr_numof_xs, error); fflush(stdout); curr_numof_xs += numof_xs_step; } } if (best_polynomial.deg != DISPOSED_POLYNOMIAL_DEG) { printf("The best polynomial is: "); printPolynomial(&best_polynomial, stdout); putchar('\n'); } disposePolynomial(&best_polynomial); }
void makeLagrangePolynomial(Polynomial *polynomial, Table const *table) { size_t const size = table->xs.size; initPolynomial(polynomial, size - 1); setToScalar(polynomial, 0.0); Polynomial term; initPolynomial(&term, polynomial->deg); for (size_t k = 0; k < size; ++k) { setToScalar(&term, 1.0); for (size_t j = 0; j < size; ++j) { if (j != k) { addRoot(&term, table->xs.values[j]); } } long double denominator = 1.0; long double const xk = table->xs.values[k]; for (size_t j = 0; j < size; ++j) { denominator *= (j == k ? 1.0 : xk - table->xs.values[j]); } multiplyByScalar(&term, table->ys.values[k] / denominator); addPolynomial(polynomial, &term); } disposePolynomial(&term); }
int readPolynomial(Polynomial *polynomial, FILE *fd) { if (fscanf(fd, "%d", &polynomial->deg) != 1 || polynomial->deg < 0) { polynomial->deg = DISPOSED_POLYNOMIAL_DEG; return READ_POLYNOMIAL_ERROR; } initPolynomial(polynomial, polynomial->deg); for (int i = polynomial->deg; i >= 0; --i) { if (fscanf(fd, "%Lf", &polynomial->coeffs[i]) != 1) { disposePolynomial(polynomial); return READ_POLYNOMIAL_ERROR; } } polynomial->effective_deg = polynomial->deg; return READ_POLYNOMIAL_OK; }
Polynomial readPolynomial(FILE *fp) { int tk; Polynomial poly; initPolynomial(&poly); /*! 读取关键词polynomial */ while ((tk=getToken(fp))=='#' ) skipOneLine(fp); /*忽略注释行 */ if ( tk!='p' ) { printf("Error in finding polynomial\n"); return poly; } /*! 读取单项式*/ while ((tk=getToken(fp))=='t' ) { PolyNode n, *p; readPolyNode(&n); p = newNode(); *p = n; insertNodeByExpo(p, &poly); } return poly; }
Polynomial mulPolynomial(Polynomial *polyA, Polynomial *polyB) { Polynomial prod; PolyNode *a, *b, *n; initPolynomial(&prod); /* make zero */ /* for each pair of combination */ for( a=polyA->head; a; a=a->next ) { for( b=polyB->head; b; b=b->next ) { int e = a->expo + b->expo; n = findNodeByExpo(&prod, e); if( n ) n->coef += a->coef*b->coef; else { n = newNode(); n->expo = e; n->coef = a->expo + b->expo; insertNodeByExpo(n, &prod); } } } removeZeroNode(&prod); return prod; }