Exemple #1
0
// 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;
  }

}
Exemple #2
0
// 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);
  }
}