// Calculate function required for the approximation. bigfloat AlgRemez::func(const bigfloat x) { bigfloat z = (bigfloat)power_num / (bigfloat)power_den; bigfloat y; if (x == (bigfloat)1.0) y = (bigfloat)1.0; else y = pow_bf(x,z); if (a_length > 0) { bigfloat sum = 0l; for (int j=0; j<a_length; j++) sum += a[j]*pow_bf(x,a_power[j]); return y * exp_bf(sum); } else { return y; } }
// Calculate function required for the approximation bigfloat AlgRemez::func(const bigfloat x) { char *fname = "func(bigfloat)"; // VRB.Func(cname,fname); bigfloat z,y,dy,f=1l,df; switch (approx_type) { case RATIONAL_APPROX_POWER: case RATIONAL_APPROX_ZERO_POLE: z = x; break; case RATIONAL_APPROX_QUOTIENT: z = x/(x+delta_m); break; default: ERR.General(cname,fname,"ApproxType %d not implemented\n", approx_type); } #ifdef USE_MPFR if (approx_type == RATIONAL_APPROX_POWER || approx_type == RATIONAL_APPROX_QUOTIENT) { if (z == (bigfloat)1.0) return (bigfloat)1.0; else return pow_bf(z,(bigfloat)power_num / (bigfloat)power_den); } #endif // initial guess to accelerate convergance y = (bigfloat)pow((double)z,(double)((bigfloat)1l/(bigfloat)power_den)); while (abs_bf(f)>(bigfloat)1l/pow_bf((bigfloat)10,prec)) { // approx good to 10^(-prec) f = pow_bf(y,power_den) - z; df = (bigfloat)power_den*pow_bf(y,power_den-1);// need power_den-1 because of diff dy = f/df; y -= dy; } if (approx_type == RATIONAL_APPROX_POWER || approx_type == RATIONAL_APPROX_QUOTIENT) { return pow_bf(y,power_num); } else if (approx_type == RATIONAL_APPROX_ZERO_POLE) { if (power_num > power_den) return pow_bf(y,power_num-power_den); else return (bigfloat)1.0/pow_bf(y,power_den-power_num); } }