gsl_integration_qagil(Func <double, double> f, double b, double epsabs, double epsrel, int limit, gsl_integration_workspace workspace, out double result, out double abserr, gsl_integration_rule q, bool bDebug) { //int status; // gsl_function f_transform; var transform_params = new il_params { b = b, f = f }; // f_transform.function = &il_transform; // f_transform.params = &transform_params; Func <double, double> f_transform = delegate(double t) { return(il_transform(t, transform_params)); }; GSL_ERROR status = qags(f_transform, 0.0, 1.0, epsabs, epsrel, limit, workspace, out result, out abserr, q, bDebug); return(status); }
gsl_integration_qawf(Func <double, double> f, double a, double epsabs, int limit, gsl_integration_workspace workspace, gsl_integration_workspace cycle_workspace, gsl_integration_qawo_table wf, out double result, out double abserr, bool bDebug) { double area, errsum; double res_ext, err_ext; double correc, total_error = 0.0, truncation_error = 0; int ktmin = 0; int iteration = 0; var table = new extrapolation_table(); double cycle; double omega = wf.omega; double p = 0.9; double factor = 1; double initial_eps, eps; int error_type = 0; /* Initialize results */ workspace.initialise(a, a); result = 0; abserr = 0; if (limit > workspace.limit) { return(new GSL_ERROR("iteration limit exceeds available workspace", GSL_ERR.GSL_EINVAL, bDebug)); } /* Test on accuracy */ if (epsabs <= 0) { return(new GSL_ERROR("absolute tolerance epsabs must be positive", GSL_ERR.GSL_EBADTOL, bDebug)); } if (omega == 0.0) { if (wf.sine == gsl_integration_qawo_enum.GSL_INTEG_SINE) { /* The function sin(w x) f(x) is always zero for w = 0 */ result = 0; abserr = 0; return(null); // GSL_SUCCESS; } else { /* The function cos(w x) f(x) is always f(x) for w = 0 */ GSL_ERROR status = QagiuIntegration.gsl_integration_qagiu(f, a, epsabs, 0.0, cycle_workspace.limit, cycle_workspace, out result, out abserr, QagiuIntegration.DefaultIntegrationRule, QagiuIntegration.DefaultDebugFlag); return(status); } } if (epsabs > GSL_CONST.GSL_DBL_MIN / (1 - p)) { eps = epsabs * (1 - p); } else { eps = epsabs; } initial_eps = eps; area = 0; errsum = 0; res_ext = 0; err_ext = GSL_CONST.GSL_DBL_MAX; correc = 0; cycle = (2 * Math.Floor(Math.Abs(omega)) + 1) * Math.PI / Math.Abs(omega); wf.set_length(cycle); table.initialise_table(); for (iteration = 0; iteration < limit; iteration++) { double a1 = a + iteration * cycle; double b1 = a1 + cycle; double epsabs1 = eps * factor; GSL_ERROR status = gsl_integration_qawo(f, a1, epsabs1, 0.0, limit, cycle_workspace, wf, out var area1, out var error1, false); workspace.append_interval(a1, b1, area1, error1); factor *= p; area = area + area1; errsum = errsum + error1; /* estimate the truncation error as 50 times the final term */ truncation_error = 50 * Math.Abs(area1); total_error = errsum + truncation_error; if (total_error < epsabs && iteration > 4) { goto compute_result; } if (error1 > correc) { correc = error1; } if (null != status) { eps = Math.Max(initial_eps, correc * (1.0 - p)); } if (null != status && total_error < 10 * correc && iteration > 3) { goto compute_result; } table.append_table(area); if (table.n < 2) { continue; } table.qelg(out var reseps, out var erreps); ktmin++; if (ktmin >= 15 && err_ext < 0.001 * total_error) { error_type = 4; } if (erreps < err_ext) { ktmin = 0; err_ext = erreps; res_ext = reseps; if (err_ext + 10 * correc <= epsabs) { break; } if (err_ext <= epsabs && 10 * correc >= epsabs) { break; } } } if (iteration == limit) { error_type = 1; } if (err_ext == GSL_CONST.GSL_DBL_MAX) { goto compute_result; } err_ext = err_ext + 10 * correc; result = res_ext; abserr = err_ext; if (error_type == 0) { return(null); // GSL_SUCCESS; } if (res_ext != 0.0 && area != 0.0) { if (err_ext / Math.Abs(res_ext) > errsum / Math.Abs(area)) { goto compute_result; } } else if (err_ext > errsum) { goto compute_result; } else if (area == 0.0) { goto return_error; } if (error_type == 4) { err_ext = err_ext + truncation_error; } goto return_error; compute_result: result = area; abserr = total_error; return_error: if (error_type > 2) { error_type--; } if (error_type == 0) { return(null); // GSL_SUCCESS; } else if (error_type == 1) { return(new GSL_ERROR("number of iterations was insufficient", GSL_ERR.GSL_EMAXITER, bDebug)); } else if (error_type == 2) { return(new GSL_ERROR("cannot reach tolerance because of roundoff error", GSL_ERR.GSL_EROUND, bDebug)); } else if (error_type == 3) { return(new GSL_ERROR("bad integrand behavior found in the integration interval", GSL_ERR.GSL_ESING, bDebug)); } else if (error_type == 4) { return(new GSL_ERROR("roundoff error detected in the extrapolation table", GSL_ERR.GSL_EROUND, bDebug)); } else if (error_type == 5) { return(new GSL_ERROR("integral is divergent, or slowly convergent", GSL_ERR.GSL_EDIVERGE, bDebug)); } else { return(new GSL_ERROR("could not integrate function", GSL_ERR.GSL_EFAILED, bDebug)); } }