/** * @brief Free a not more useful mps_context. * * @param s the mps_context struct pointer to free. */ void mps_context_free (mps_context * s) { if (s->initialized) mps_free_data (s); free (s->input_config); free (s->output_config); /* Check if secular equation or monomial poly need to be freed */ if (s->active_poly != NULL) mps_polynomial_free (s, s->active_poly); s->active_poly = NULL; if (s->secular_equation) mps_secular_equation_free (s, MPS_POLYNOMIAL (s->secular_equation)); /* Close input and output streams if they're not stdin, stdout and * stderr */ if (s->instr != stdin && s->instr != NULL) fclose (s->instr); if (s->logstr != stderr && s->logstr != stdout && s->logstr != NULL) fclose (s->logstr); free (s); }
void* cleanup_context (mps_context * ctx, void * user_data) { /* Check for errors */ if (mps_context_has_errors (ctx)) { mps_print_errors (ctx); return NULL; } /* Output the roots */ mps_output (ctx); #ifdef HAVE_GRAPHICAL_DEBUGGER if (logger_closed) gtk_main_quit (); else if (logger) { /* In the other case copy the approximation in the right place * so the logger can display them again. */ int i = 0; mps_approximation ** approximations = malloc (sizeof (mps_approximation*) * ctx->n); for (i = 0; i < ctx->n; i++) approximations[i] = mps_approximation_copy (ctx, ctx->root[i]); mps_iteration_logger_set_roots (logger, approximations, ctx->n); } #endif /* Free used data */ if (poly) mps_polynomial_free (ctx, poly); mps_context_free (ctx); s = NULL; return NULL; }
/** * @brief This function tests the resolution of a polynomial file * referenced by <code>pol</code>. */ int test_secsolve_on_pol_impl (test_pol * pol, mps_output_goal goal, mps_boolean jacobi_iterations) { mpc_t root, ctmp; mps_boolean passed = true; int i, j, zero_roots = 0; char ch; rdpe_t eps; mps_polynomial * poly = NULL; /* Check the roots */ FILE* result_stream = fopen (pol->res_file, "r"); FILE* input_stream = fopen (pol->pol_file, "r"); rdpe_set_2dl (eps, 1.0, -pol->out_digits); if (!result_stream) { error_test_message ("no results file found", pol->pol_file); return EXIT_FAILURE; } if (!input_stream) { error_test_message ("no polynomial file found", pol->pol_file); return EXIT_FAILURE; } /* Create a new empty mps_context */ mps_context * s = mps_context_new (); if ((getenv ("MPS_VERBOSE_TEST") && strstr (pol->pol_file, getenv ("MPS_VERBOSE_TEST"))) || pol->DOLOG) mps_context_set_debug_level (s, MPS_DEBUG_TRACE); /* Load the polynomial that has been given to us */ poly = mps_parse_stream (s, input_stream); mps_context_set_input_poly (s, poly); starting_test_message (pol->pol_file); mps_context_set_output_prec (s, pol->out_digits); mps_context_set_output_goal (s, goal); mps_context_set_jacobi_iterations (s, jacobi_iterations); /* Solve it */ mps_context_select_algorithm (s, (pol->ga) ? MPS_ALGORITHM_SECULAR_GA : MPS_ALGORITHM_STANDARD_MPSOLVE); mps_mpsolve (s); mpc_init2 (root, mps_context_get_data_prec_max (s)); mpc_init2 (ctmp, mps_context_get_data_prec_max (s)); /* Test if roots are equal to the roots provided in the check */ passed = true; rdpe_t * drad = rdpe_valloc (mps_context_get_degree (s)); mpc_t * mroot = mpc_valloc (mps_context_get_degree (s)); mpc_vinit2 (mroot, mps_context_get_degree (s), mps_context_get_data_prec_max (s)); mps_context_get_roots_m (s, &mroot, &drad); for (i = 0; i < mps_context_get_degree (s); i++) { rdpe_t rtmp; cdpe_t cdtmp; rdpe_t min_dist; int found_root = 0; rdpe_t exp_drad; while (isspace (ch = getc (result_stream))) ; ungetc (ch, result_stream); mpc_inp_str (root, result_stream, 10); if (mpc_eq_zero (root)) { zero_roots++; /* We need to read it another time. This seems a bug in * mpc_inp_str, but I don't get why is necessary. */ mpc_inp_str (root, result_stream, 10); continue; } mpc_sub (ctmp, root, mroot[0]); mpc_get_cdpe (cdtmp, ctmp); cdpe_mod (rtmp, cdtmp); rdpe_set (min_dist, rtmp); if (getenv ("MPS_VERBOSE_TEST") && (strstr (pol->pol_file, getenv ("MPS_VERBOSE_TEST")))) { printf ("Read root_%d = ", i); mpc_out_str_2 (stdout, 10, mps_context_get_data_prec_max (s), mps_context_get_data_prec_max (s), root); printf ("\n"); } for (j = 1; j < mps_context_get_degree (s); j++) { mpc_sub (ctmp, root, mroot[j]); mpc_get_cdpe (cdtmp, ctmp); cdpe_mod (rtmp, cdtmp); if (rdpe_le (rtmp, min_dist)) { rdpe_set (min_dist, rtmp); found_root = j; } } mpc_get_cdpe (cdtmp, mroot[found_root]); cdpe_mod (rtmp, cdtmp); rdpe_mul_eq (rtmp, eps); rdpe_set (exp_drad, rtmp); rdpe_div_eq_d (min_dist, 1 + 4.0 * DBL_EPSILON); if ((!rdpe_le (min_dist, drad[found_root]) && !rdpe_gt (drad[found_root], exp_drad)) && !mps_context_get_over_max (s)) { passed = false; if (getenv ("MPS_VERBOSE_TEST") && (strstr (pol->pol_file, getenv ("MPS_VERBOSE_TEST")))) { printf ("Failing on root %d, with min_dist = ", found_root); rdpe_out_str (stdout, min_dist); printf ("\ndrad_%d", found_root); rdpe_out_str (stdout, drad[found_root]); printf ("\n"); printf ("Approximation_%d = ", found_root); mpc_out_str_2 (stdout, 10, -rdpe_Esp (drad[found_root]), -rdpe_Esp (drad[found_root]), mroot[found_root]); printf ("\n"); } } } if (zero_roots != mps_context_get_zero_roots (s)) passed = false; if ((getenv ("MPS_VERBOSE_TEST") && strstr (pol->pol_file, getenv ("MPS_VERBOSE_TEST"))) || pol->DOLOG) { /* mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_GNUPLOT_FULL); */ mps_output (s); } fclose (result_stream); mpc_clear (ctmp); mpc_clear (root); mpc_vclear (mroot, mps_context_get_degree (s)); free (mroot); free (drad); mps_polynomial_free (s, poly); mps_context_free (s); if (passed) success_test_message (pol->pol_file); else failed_test_message (pol->pol_file); if (getenv ("MPS_VERBOSE_TEST")) fail_unless (passed == true, "Computed results are not exact to the required " "precision.\n" "\n" " Dumping test configuration: \n" " => Polynomial file: %s;\n" " => Required digits: %d\n" " => Gemignani's approach: %s;\n" " => Starting phase: %s;\n", pol->pol_file, pol->out_digits, mps_boolean_to_string (pol->ga), (pol->phase == float_phase) ? "float_phase" : "dpe_phase"); else fail_unless (passed == true, "Computed results are not exact to the required precision"); return passed; }