Beispiel #1
0
db_atoms
database_rep::query (tree ql, db_time t, int limit) {
    //cout << "query " << ql << ", " << t << ", " << limit << LF;
    ql= normalize_query (ql);
    //cout << "normalized query " << ql << ", " << t << ", " << limit << LF;
    db_atoms ids= ansatz (ql, t);
    //cout << "ansatz ids= " << ids << LF;
    bool sort_flag= false;
    if (is_tuple (ql))
        for (int i=0; i<N(ql); i++)
            sort_flag= sort_flag || is_tuple (ql[i], "order", 2);
    ids= filter (ids, ql, t, max (limit, sort_flag? 1000: 0));
    //cout << "filtered ids= " << ids << LF;
    for (int i=0; i<N(ql); i++) {
        if (is_tuple (ql[i], "modified", 2) &&
                is_atomic (ql[i][1]) && is_atomic (ql[i][2]) &&
                is_quoted (ql[i][1]->label) && is_quoted (ql[i][2]->label)) {
            string t1= scm_unquote (ql[i][1]->label);
            string t2= scm_unquote (ql[i][2]->label);
            if (is_int (t1) && is_int (t2))
                ids= filter_modified (ids, (db_time) as_long_int (t1),
                                      (db_time) as_long_int (t2));
        }
    }
    //cout << "filtered on modified ids= " << ids << LF;
    ids= sort_results (ids, ql, t);
    //cout << "sorted ids= " << ids << LF;
    if (N(ids) > limit) ids= range (ids, 0, limit);
    return ids;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    char *file_name = " Usage: -f filename";
    CALC_MODE mode = CM_OVERLAP;    // 計算する方式
    int is_chaged = 1;              // 計算方法に変更があったか
    ACTION act;                     // 操作を選択
    int threshold = 2;       // 計算に用いる出現頻度の最小値
    int i;
    
    init(); // 要素の確保
    
    // コマンドライン引数の読み込み
    for (i = 0; i < argc; i++)
    {
        if (strcmp(argv[i], "-f") == 0 && i + 1 < argc) // 次の文字列があれば
            file_name = argv[i + 1];    // 開くファイルを読み込む
    }

    read_file(file_name);   // ファイル読み込み
    printf("\nFinished Reading File\n");
    printf("Total number of documents read = %d\n", n_docs);
    printf("Total number of words in the index = %d\n", n_words);
    fflush(stdout);
    
    printf("\nCurrent Indicator Type: %s, Threshold: %d\n",
           mode_string[mode], threshold);
    
    while (1)
    {
        if (is_chaged)  // 変更があった場合
        {
            free_results(); // 前回の結果の消去
            // 次回の計算用
            results = (RESULTS **)malloc(sizeof(RESULTS *) * n_results_max);
            if (results == NULL)
            {
                fprintf(stderr, "Memory Allocation Error\n");
                exit(1);
            }
            
            calc_indicator(mode, threshold);    // 強度の計算
            printf("\nCalculation Finished\n");
            fflush(stdout);
            
            sort_results();     // 結果のソート
            printf("\nSort Finished\n");
            fflush(stdout);
        }
        
        
        printf("\nCurrent Indicator Type: %s, Threshold: %d\n",
               mode_string[mode], threshold);
        
        printf("Choose Action (-1:Quit)\n");
        printf("0:Show Results     1:Change Indicator \n");
        printf("2:Change Precision 3:Write to Csv \n> ");
        act = read_input_as_int();  // 操作を選択
        
        switch (act)
        {
            case A_QUIT:    // 終了
                free_all();
                printf("Quit\n");
                return 0;
                
            case A_SHOW_RESULTS:
                show_results_in_range();        // 結果の表示
                is_chaged = 0;
                break;
                
            case A_CHANGE_INDICATOR:            // 計算方法の変更
                is_chaged = change_mode(&mode);
                break;
            
            case A_CHANGE_PRECISION:
                is_chaged = change_threshold(&threshold); // 計算に用いるときの閾値(頻度)の変更
                break;
                
            case A_WRITE_CSV:
                write_to_csv_in_range();        // CSV形式で書き出し
                is_chaged = 0;
                break;
                
            default:
                break;
        }
        
    }
    
    return 0;
}
Beispiel #3
0
int CLIENT_STATE::parse_state_file_aux(const char* fname) {
    PROJECT *project=NULL;
    int retval=0;
    string stemp;

    FILE* f = fopen(fname, "r");
    if (!f) return ERR_FOPEN;
    MIOFILE mf;
    XML_PARSER xp(&mf);
    mf.init_file(f);
    while (!xp.get_tag()) {
        if (xp.match_tag("/client_state")) {
            break;
        }
        if (xp.match_tag("client_state")) {
            continue;
        }
        if (xp.match_tag("project")) {
            PROJECT temp_project;
            retval = temp_project.parse_state(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR, "Can't parse project in state file");
            } else {
#ifdef SIM
                project = new PROJECT;
                *project = temp_project;
                projects.push_back(project);
#else
                project = lookup_project(temp_project.master_url);
                if (project) {
                    project->copy_state_fields(temp_project);
                } else {
                    msg_printf(&temp_project, MSG_INTERNAL_ERROR,
                        "Project %s is in state file but no account file found",
                        temp_project.get_project_name()
                    );
                }
#endif
            }
            continue;
        }
        if (xp.match_tag("app")) {
            APP* app = new APP;
            retval = app->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Application %s outside project in state file",
                    app->name
                );
                delete app;
                continue;
            }
            if (project->anonymous_platform) {
                delete app;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse application in state file"
                );
                delete app;
                continue;
            }
            retval = link_app(project, app);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't handle application %s in state file",
                    app->name
                );
                delete app;
                continue;
            }
            apps.push_back(app);
            continue;
        }
        if (xp.match_tag("file_info") || xp.match_tag("file")) {
            FILE_INFO* fip = new FILE_INFO;
            retval = fip->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "File info outside project in state file"
                );
                delete fip;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't handle file info in state file"
                );
                delete fip;
                continue;
            }
            retval = link_file_info(project, fip);
            if (project->anonymous_platform && retval == ERR_NOT_UNIQUE) {
                delete fip;
                continue;
            }
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't handle file info %s in state file",
                    fip->name
                );
                delete fip;
                continue;
            }
            file_infos.push_back(fip);
#ifndef SIM
            // If the file had a failure before,
            // don't start another file transfer
            //
            int failnum;
            if (fip->had_failure(failnum)) {
                if (fip->pers_file_xfer) {
                    delete fip->pers_file_xfer;
                    fip->pers_file_xfer = NULL;
                }
            }
            if (fip->pers_file_xfer) {
                retval = fip->pers_file_xfer->init(fip, fip->pers_file_xfer->is_upload);
                if (retval) {
                    msg_printf(project, MSG_INTERNAL_ERROR,
                        "Can't initialize file transfer for %s",
                        fip->name
                    );
                }
                retval = pers_file_xfers->insert(fip->pers_file_xfer);
                if (retval) {
                    msg_printf(project, MSG_INTERNAL_ERROR,
                        "Can't start persistent file transfer for %s",
                        fip->name
                    );
                }
            }
#endif
            continue;
        }
        if (xp.match_tag("app_version")) {
            APP_VERSION* avp = new APP_VERSION;
            retval = avp->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Application version outside project in state file"
                );
                delete avp;
                continue;
            }
            if (project->anonymous_platform) {
                delete avp;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse application version in state file"
                );
                delete avp;
                continue;
            } 
            if (strlen(avp->platform) == 0) {
                safe_strcpy(avp->platform, get_primary_platform());
            } else {
                if (!is_supported_platform(avp->platform)) {
                    // if it's a platform we haven't heard of,
                    // must be that the user tried out a 64 bit client
                    // and then reverted to a 32-bit client.
                    // Let's not throw away the app version and its WUs
                    //
#ifndef SIM
                    msg_printf(project, MSG_INTERNAL_ERROR,
                        "App version has unsupported platform %s; changing to %s",
                        avp->platform, get_primary_platform()
                    );
#endif
                    safe_strcpy(avp->platform, get_primary_platform());
                }
            }
            if (avp->missing_coproc) {
                msg_printf(project, MSG_INFO,
                    "Application uses missing %s GPU",
                    avp->missing_coproc_name
                );
            }
            retval = link_app_version(project, avp);
            if (retval) {
                delete avp;
                continue;
            }
            app_versions.push_back(avp);
            continue;
        }
        if (xp.match_tag("workunit")) {
            WORKUNIT* wup = new WORKUNIT;
            retval = wup->parse(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Workunit outside project in state file"
                );
                delete wup;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse workunit in state file"
                );
                delete wup;
                continue;
            }
            retval = link_workunit(project, wup);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't handle workunit in state file"
                );
                delete wup;
                continue;
            }
            workunits.push_back(wup);
            continue;
        }
        if (xp.match_tag("result")) {
            RESULT* rp = new RESULT;
            retval = rp->parse_state(xp);
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Task %s outside project in state file",
                    rp->name
                );
                delete rp;
                continue;
            }
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse task in state file"
                );
                delete rp;
                continue;
            }
            retval = link_result(project, rp);
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't link task %s in state file",
                    rp->name
                );
                delete rp;
                continue;
            }
            // handle transition from old clients which didn't store result.platform;
            // skip for anon platform
            if (!project->anonymous_platform) {
                if (!strlen(rp->platform) || !is_supported_platform(rp->platform)) {
                    safe_strcpy(rp->platform, get_primary_platform());
                    rp->version_num = latest_version(rp->wup->app, rp->platform);
                }
            }
            rp->avp = lookup_app_version(
                rp->wup->app, rp->platform, rp->version_num, rp->plan_class
            );
            if (!rp->avp) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "No application found for task: %s %d %s; discarding",
                    rp->platform, rp->version_num, rp->plan_class
                );
                delete rp;
                continue;
            }
            if (rp->avp->missing_coproc) {
                msg_printf(project, MSG_INFO,
                    "Missing coprocessor for task %s", rp->name
                );
                rp->coproc_missing = true;
            }
            rp->wup->version_num = rp->version_num;
            results.push_back(rp);
            continue;
        }
        if (xp.match_tag("project_files")) {
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Project files outside project in state file"
                );
                xp.skip_unexpected();
                continue;
            }
            parse_project_files(xp, project->project_files);
            project->link_project_files();
            continue;
        }
        if (xp.match_tag("host_info")) {
#ifdef SIM
            retval = host_info.parse(xp, false);
            coprocs = host_info.coprocs;
            coprocs.bound_counts();
#else
            retval = host_info.parse(xp, true);
#endif
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse host info in state file"
                );
            }
            continue;
        }
        if (xp.match_tag("time_stats")) {
            retval = time_stats.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse time stats in state file"
                );
            }
            continue;
        }
        if (xp.match_tag("net_stats")) {
            retval = net_stats.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse network stats in state file"
                );
            }
            continue;
        }
        if (xp.match_tag("active_task_set")) {
            retval = active_tasks.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse active tasks in state file"
                );
            }
            continue;
        }
        if (xp.parse_string("platform_name", statefile_platform_name)) {
            continue;
        }
        if (xp.parse_string("alt_platform", stemp)) {
            continue;
        }
        if (xp.parse_int("user_run_request", retval)) {
            cpu_run_mode.set(retval, 0);
            continue;
        }
        if (xp.parse_int("user_run_prev_request", retval)) {
            cpu_run_mode.set_prev(retval);
            continue;
        }
        if (xp.parse_int("user_gpu_request", retval)) {
            gpu_run_mode.set(retval, 0);
            continue;
        }
        if (xp.parse_int("user_gpu_prev_request", retval)) {
            gpu_run_mode.set_prev(retval);
            continue;
        }
        if (xp.parse_int("user_network_request", retval)) {
            network_run_mode.set(retval, 0);
            continue;
        }
        if (xp.parse_int("core_client_major_version", old_major_version)) {
            continue;
        }
        if (xp.parse_int("core_client_minor_version", old_minor_version)) {
            continue;
        }
        if (xp.parse_int("core_client_release", old_release)) {
            continue;
        }
        if (xp.parse_str("language", language, sizeof(language))) {
            continue;
        }
        if (xp.match_tag("proxy_info")) {
            retval = gui_proxy_info.parse(xp);
            if (retval) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Can't parse proxy info in state file"
                );
            }
            continue;
        }
        if (xp.parse_str("host_venue", main_host_venue, sizeof(main_host_venue))) {
            continue;
        }
        if (xp.parse_double("new_version_check_time", new_version_check_time)) {
            continue;
        }
        if (xp.parse_double("all_projects_list_check_time", all_projects_list_check_time)) {
            continue;
        }
        if (xp.parse_string("newer_version", newer_version)) {
            continue;
        }
#ifdef ENABLE_AUTO_UPDATE
        if (xp.match_tag("auto_update")) {
            if (!project) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "auto update outside project in state file"
                );
                xp.skip_unexpected();
                continue;
            }
            if (!auto_update.parse(xp) && !auto_update.validate_and_link(project)) {
                auto_update.present = true;
            }
            continue;
        }
#endif
        if (log_flags.unparsed_xml) {
            msg_printf(0, MSG_INFO,
                "[unparsed_xml] state_file: unrecognized: %s",
                xp.parsed_tag
            );
        }
        xp.skip_unexpected();
    }
    sort_results();
    fclose(f);
    
    // if total resource share is zero, set all shares to 1
    //
    if (projects.size()) {
        unsigned int i;
        double x=0;
        for (i=0; i<projects.size(); i++) {
            x += projects[i]->resource_share;
        }
        if (!x) {
            msg_printf(NULL, MSG_INFO,
                "All projects have zero resource share; setting to 100"
            );
            for (i=0; i<projects.size(); i++) {
                projects[i]->resource_share = 100;
            }
        }
    }
    return 0;
}
Beispiel #4
0
/* do_search()
 * Description: Perform a lookup of the specified search string in all Clear manifests
 * for the current os release.
 */
static void do_search(struct manifest *MoM, char search_type, char *search_term)
{
	struct list *list;
	struct list *sublist;
	struct file *file;
	struct file *subfile;
	struct list *bundle_info = NULL;
	struct manifest *subman = NULL;
	int i;
	bool done_with_bundle, done_with_search = false;
	bool hit = false;
	bool man_load_failures = false;
	long hit_count = 0;

	list = MoM->manifests;
	while (list && !done_with_search) {
		file = list->data;
		list = list->next;
		done_with_bundle = false;

		/* Load sub-manifest */
		subman = load_manifest(file->last_change, file, MoM, false);
		if (!subman) {
			fprintf(stderr, "Failed to load manifest %s\n", file->filename);
			man_load_failures = true;
			continue;
		}

		/* record contentsize and includes for install size calculation */
		struct bundle_result *bundle = NULL;
		bundle = calloc(sizeof(struct bundle_result), 1);
		ON_NULL_ABORT(bundle);
		/* copy relevant information over for future use */
		strncpy(bundle->bundle_name, subman->component, BUNDLE_NAME_MAXLEN - 1);
		bundle->topsize = subman->contentsize;
		/* do a deep copy of the includes list */
		bundle->includes = list_deep_clone_strs(subman->includes);
		bundle_info = list_prepend_data(bundle_info, bundle);

		if (display_files) {
			/* Display bundle name. Marked up for pattern matchability */
			fprintf(stderr, "--Bundle: %s--\n", file->filename);
		}

		/* Loop through sub-manifest, searching for files matching the desired pattern */
		sublist = subman->files;
		while (sublist && !done_with_bundle) {
			subfile = sublist->data;
			sublist = sublist->next;

			if ((!subfile->is_file) && (!subfile->is_link)) {
				continue;
			}

			if (display_files) {
				/* Just display filename */
				file_search(subfile->filename, NULL, NULL);
			} else if (search_type == '0') {
				/* Search for exact match, not path addition */
				if (file_search(subfile->filename, "", search_term)) {
					report_find(file->filename, subfile->filename, search_term);
					hit = true;
				}
			} else if (search_type == 'l') {
				/* Check each supported library path for a match */
				for (i = 0; lib_paths[i] != NULL; i++) {
					if (file_search(subfile->filename, lib_paths[i], search_term)) {
						report_find(file->filename, subfile->filename, search_term);
						hit = true;
					}
				}
			} else if (search_type == 'b') {
				/* Check each supported path for binaries */
				for (i = 0; bin_paths[i] != NULL; i++) {
					if (file_search(subfile->filename, bin_paths[i], search_term)) {
						report_find(file->filename, subfile->filename, search_term);
						hit = true;
					}
				}
			} else {
				fprintf(stderr, "Unrecognized search type. -b or -l supported\n");
				done_with_search = true;
				break;
			}

			/* Determine the level of completion we've reached */
			if (hit) {
				if (scope == 'b') {
					done_with_bundle = true;
				} else if (scope == 'o') {
					done_with_bundle = true;
					done_with_search = true;
				}

				hit_count++;
			}
			hit = false;
		}

		free_manifest(subman);
	}

	if (!hit_count) {
		fprintf(stderr, "Search term not found.\n");
	}

	bool display_size = (scope != 'o' && !man_load_failures);
	if (display_size) {
		apply_size_penalty(bundle_info);
	}
	list_free_list_and_data(bundle_info, free_bundle_result_data);

	if (num_results != INT_MAX) {
		sort_results();
	} else {
		results = list_sort(results, bundle_size_cmp);
	}

	if (csv_format) {
		print_csv_results();
	} else {
		print_final_results(display_size);
	}
	list_free_list_and_data(results, free_bundle_result_data);
}
Beispiel #5
0
static int
qagp (const gsl_function * f,
      const double *pts, const size_t npts,
      const double epsabs, const double epsrel, 
      const size_t limit,
      gsl_integration_workspace * workspace,
      double *result, double *abserr,
      gsl_integration_rule * q)
{
  double area, errsum;
  double res_ext, err_ext;
  double result0, abserr0, resabs0;
  double tolerance;

  double ertest = 0;
  double error_over_large_intervals = 0;
  double reseps = 0, abseps = 0, correc = 0;
  size_t ktmin = 0;
  int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0;
  int error_type = 0, error_type2 = 0;

  size_t iteration = 0;

  int positive_integrand = 0;
  int extrapolate = 0;
  int disallow_extrapolation = 0;

  struct extrapolation_table table;

  const size_t nint = npts - 1; /* number of intervals */

  size_t *ndin = workspace->level; /* temporarily alias ndin to level */

  size_t i;

  /* Initialize results */

  *result = 0;
  *abserr = 0;

  /* Test on validity of parameters */

  if (limit > workspace->limit)
    {
      GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ;
    }

  if (npts > workspace->limit)
    {
      GSL_ERROR ("npts exceeds size of workspace", GSL_EINVAL);
    }

  if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28))
    {
      GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel",
                 GSL_EBADTOL);
    }

  /* Check that the integration range and break points are an
     ascending sequence */

  for (i = 0; i < nint; i++)
    {
      if (pts[i + 1] < pts[i])
        {
          GSL_ERROR ("points are not in an ascending sequence", GSL_EINVAL);
        }
    }

  /* Perform the first integration */

  result0 = 0;
  abserr0 = 0;
  resabs0 = 0;

  initialise (workspace, 0.0, 0.0) ;

  for (i = 0; i < nint; i++)
    {
      double area1, error1, resabs1, resasc1;
      const double a1 = pts[i];
      const double b1 = pts[i + 1];

      q (f, a1, b1, &area1, &error1, &resabs1, &resasc1);

      result0 = result0 + area1;
      abserr0 = abserr0 + error1;
      resabs0 = resabs0 + resabs1;

      append_interval (workspace, a1, b1, area1, error1);

      if (error1 == resasc1 && error1 != 0.0)
        {
          ndin[i] = 1;
        }
      else
        {
          ndin[i] = 0;
        }
    }

  /* Compute the initial error estimate */

  errsum = 0.0;

  for (i = 0; i < nint; i++)
    {
      if (ndin[i])
        {
          workspace->elist[i] = abserr0;
        }

      errsum = errsum + workspace->elist[i];

    }

  for (i = 0; i < nint; i++)
    {
      workspace->level[i] = 0;
    }

  /* Sort results into order of decreasing error via the indirection
     array order[] */

  sort_results (workspace);

  /* Test on accuracy */

  tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0));

  if (abserr0 <= 100 * GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance)
    {
      *result = result0;
      *abserr = abserr0;

      GSL_ERROR ("cannot reach tolerance because of roundoff error"
                 "on first attempt", GSL_EROUND);
    }
  else if (abserr0 <= tolerance)
    {
      *result = result0;
      *abserr = abserr0;

      return GSL_SUCCESS;
    }
  else if (limit == 1)
    {
      *result = result0;
      *abserr = abserr0;

      GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER);
    }

  /* Initialization */

  initialise_table (&table);
  append_table (&table, result0);

  area = result0;

  res_ext = result0;
  err_ext = GSL_DBL_MAX;

  error_over_large_intervals = errsum;
  ertest = tolerance;

  positive_integrand = test_positivity (result0, resabs0);

  iteration = nint - 1; 

  do
    {
      size_t current_level;
      double a1, b1, a2, b2;
      double a_i, b_i, r_i, e_i;
      double area1 = 0, area2 = 0, area12 = 0;
      double error1 = 0, error2 = 0, error12 = 0;
      double resasc1, resasc2;
      double resabs1, resabs2;
      double last_e_i;

      /* Bisect the subinterval with the largest error estimate */

      retrieve (workspace, &a_i, &b_i, &r_i, &e_i);

      current_level = workspace->level[workspace->i] + 1;

      a1 = a_i;
      b1 = 0.5 * (a_i + b_i);
      a2 = b1;
      b2 = b_i;

      iteration++;

      q (f, a1, b1, &area1, &error1, &resabs1, &resasc1);
      q (f, a2, b2, &area2, &error2, &resabs2, &resasc2);

      area12 = area1 + area2;
      error12 = error1 + error2;
      last_e_i = e_i;

      /* Improve previous approximations to the integral and test for
         accuracy.

         We write these expressions in the same way as the original
         QUADPACK code so that the rounding errors are the same, which
         makes testing easier. */

      errsum = errsum + error12 - e_i;
      area = area + area12 - r_i;

      tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area));

      if (resasc1 != error1 && resasc2 != error2)
        {
          double delta = r_i - area12;

          if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i)
            {
              if (!extrapolate)
                {
                  roundoff_type1++;
                }
              else
                {
                  roundoff_type2++;
                }
            }

          if (i > 10 && error12 > e_i)
            {
              roundoff_type3++;
            }
        }

      /* Test for roundoff and eventually set error flag */

      if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20)
        {
          error_type = 2;       /* round off error */
        }

      if (roundoff_type2 >= 5)
        {
          error_type2 = 1;
        }

      /* set error flag in the case of bad integrand behaviour at
         a point of the integration range */

      if (subinterval_too_small (a1, a2, b2))
        {
          error_type = 4;
        }

      /* append the newly-created intervals to the list */

      update (workspace, a1, b1, area1, error1, a2, b2, area2, error2);

      if (errsum <= tolerance)
        {
          goto compute_result;
        }

      if (error_type)
        {
          break;
        }

      if (iteration >= limit - 1)
        {
          error_type = 1;
          break;
        }

      if (disallow_extrapolation)
        {
          continue;
        }

      error_over_large_intervals += -last_e_i;

      if (current_level < workspace->maximum_level)
        {
          error_over_large_intervals += error12;
        }

      if (!extrapolate)
        {
          /* test whether the interval to be bisected next is the
             smallest interval. */
          if (large_interval (workspace))
            continue;

          extrapolate = 1;
          workspace->nrmax = 1;
        }

      /* The smallest interval has the largest error.  Before
         bisecting decrease the sum of the errors over the larger
         intervals (error_over_large_intervals) and perform
         extrapolation. */

      if (!error_type2 && error_over_large_intervals > ertest)
        {
          if (increase_nrmax (workspace))
            continue;
        }

      /* Perform extrapolation */

      append_table (&table, area);

      if (table.n < 3) 
        {
          goto skip_extrapolation;
        } 

      qelg (&table, &reseps, &abseps);

      ktmin++;

      if (ktmin > 5 && err_ext < 0.001 * errsum)
        {
          error_type = 5;
        }

      if (abseps < err_ext)
        {
          ktmin = 0;
          err_ext = abseps;
          res_ext = reseps;
          correc = error_over_large_intervals;
          ertest = GSL_MAX_DBL (epsabs, epsrel * fabs (reseps));
          if (err_ext <= ertest)
            break;
        }

      /* Prepare bisection of the smallest interval. */

      if (table.n == 1)
        {
          disallow_extrapolation = 1;
        }

      if (error_type == 5)
        {
          break;
        }

    skip_extrapolation:

      reset_nrmax (workspace);
      extrapolate = 0;
      error_over_large_intervals = errsum;

    }
  while (iteration < limit);

  *result = res_ext;
  *abserr = err_ext;

  if (err_ext == GSL_DBL_MAX)
    goto compute_result;

  if (error_type || error_type2)
    {
      if (error_type2)
        {
          err_ext += correc;
        }

      if (error_type == 0)
        error_type = 3;

      if (result != 0 && area != 0)
        {
          if (err_ext / fabs (res_ext) > errsum / fabs (area))
            goto compute_result;
        }
      else if (err_ext > errsum)
        {
          goto compute_result;
        }
      else if (area == 0.0)
        {
          goto return_error;
        }
    }

  /*  Test on divergence. */

  {
    double max_area = GSL_MAX_DBL (fabs (res_ext), fabs (area));

    if (!positive_integrand && max_area < 0.01 * resabs0)
      goto return_error;
  }

  {
    double ratio = res_ext / area;

    if (ratio < 0.01 || ratio > 100 || errsum > fabs (area))
      error_type = 6;
  }

  goto return_error;

compute_result:

  *result = sum_results (workspace);
  *abserr = errsum;

return_error:

  if (error_type > 2)
    error_type--;

  if (error_type == 0)
    {
      return GSL_SUCCESS;
    }
  else if (error_type == 1)
    {
      GSL_ERROR ("number of iterations was insufficient", GSL_EMAXITER);
    }
  else if (error_type == 2)
    {
      GSL_ERROR ("cannot reach tolerance because of roundoff error",
                 GSL_EROUND);
    }
  else if (error_type == 3)
    {
      GSL_ERROR ("bad integrand behavior found in the integration interval",
                 GSL_ESING);
    }
  else if (error_type == 4)
    {
      GSL_ERROR ("roundoff error detected in the extrapolation table",
                 GSL_EROUND);
    }
  else if (error_type == 5)
    {
      GSL_ERROR ("integral is divergent, or slowly convergent",
                 GSL_EDIVERGE);
    }
  else
    {
      GSL_ERROR ("could not integrate function", GSL_EFAILED);
    }
}