// Generate the rational approximation x^(pnum/pden) void AlgRemez::generateApprox() { char *fname = "generateApprox()"; Float time = -dclock(); iter = 0; spread = 1.0e37; if (approx_type == RATIONAL_APPROX_ZERO_POLE) { n--; neq--; } initialGuess(); stpini(step); while (spread > tolerance) { //iterate until convergance if (iter++%100==0) VRB.Result(cname,fname,"Iteration %d, spread %e delta %e\n", iter-1,(Float)spread,(Float)delta); equations(); if (delta < tolerance) ERR.General(cname, fname,"Delta too small, try increasing precision\n"); search(step); } int sign; Float error = (Float)getErr(mm[0],&sign); VRB.Result(cname,fname,"Converged at %d iterations, error = %e\n", iter,error); //!< Once the approximation has been generated, calculate the roots if(!root()) ERR.General(cname,fname,"Root finding failed\n"); if (approx_type == RATIONAL_APPROX_ZERO_POLE) { roots[n] = (bigfloat)0.0; n++; neq++; } //!< Now find the partial fraction expansions if (remez_arg->field_type == BOSON) { getPFE(remez_arg->residue, remez_arg->pole, &(remez_arg->norm)); getIPFE(remez_arg->residue_inv, remez_arg->pole_inv, &(remez_arg->norm_inv)); } else { getIPFE(remez_arg->residue, remez_arg->pole, &(remez_arg->norm)); getPFE(remez_arg->residue_inv, remez_arg->pole_inv, &(remez_arg->norm_inv)); } remez_arg->error = error; time += dclock(); print_time(cname,fname,time); }
// Generate the rational approximation x^(pnum/pden) double AlgRemez::generateApprox(int num_degree, int den_degree, unsigned long pnum, unsigned long pden, int a_len, double *a_param, int *a_pow) { char *fname = "generateApprox(int, unsigned long, unsigned long)"; printf("Degree of the approximation is (%d,%d)\n", num_degree, den_degree); printf("Approximating the function x^(%d/%d)\n", pnum, pden); // Reallocate arrays, since degree has changed if (num_degree != n || den_degree != d) allocate(num_degree,den_degree); if (a_len > SUM_MAX) { printf("Error: a_length > SUM_MAX"); exit(0); } step = new bigfloat[num_degree+den_degree+2]; a_length = a_len; for (int j=0; j<a_len; j++) { a[j]= a_param[j]; a_power[j] = a_pow[j]; } power_num = pnum; power_den = pden; spread = 1.0e37; iter = 0; n = num_degree; d = den_degree; neq = n + d + 1; initialGuess(); stpini(step); while (spread > tolerance) { //iterate until convergance if (iter++%100==0) printf("Iteration %d, spread %e delta %e\n", iter-1,(double)spread,(double)delta); equations(); if (delta < tolerance) { printf("Delta too small, try increasing precision\n"); exit(0); } search(step); } int sign; double error = (double)getErr(mm[0],&sign); printf("Converged at %d iterations, error = %e\n",iter,error); // Once the approximation has been generated, calculate the roots if(!root()) { printf("Root finding failed\n"); } else { foundRoots = 1; } delete [] step; // Return the maximum error in the approximation return error; }