Esempio n. 1
0
int
main (int argc, char **argv)
{
#if HAVE_GRAPHICAL_DEBUGGER
  mps_boolean graphic_debug = false;
#endif

  /* Create a new status */
  s = mps_context_new ();

  /* Associate the SIGUSR1 signal to the mps_dump () function */
#ifndef __WINDOWS
  signal (SIGUSR1, status);
#endif

  /* Leave this value to -1 if not precision has been enforced
   * by the user. Otherwise, override the polynomial input
   * precision. */
  long int input_precision = -1;
  char * inline_poly = NULL;

  FILE *infile;

  /* Parse options */
  mps_opt *opt;
  mps_phase phase = no_phase;

  /* This will be true if the user has explicitely selected the algorithm, 
     otherwise we will be using our own heuristic. */
  mps_boolean explicit_algorithm_selection = false;

  opt = NULL;
  while ((mps_getopts (&opt, &argc, &argv, MPSOLVE_GETOPT_STRING)))
    {
      switch (opt->optchar)
        {
        case 'l':
          {
            FILE* logstr = fopen (opt->optvalue, "w");
            if (!logstr)
              mps_error (s, "Cannot open selected log file.");
            mps_context_set_log_stream (s, logstr);
          }
          break;

        case 'v':

#ifdef HAVE_CONFIG_H
          printf (PACKAGE_STRING "\n");
#else
          printf ("MPSolve 3.1.5\n");
#endif

          mps_context_free (s);
          exit (EXIT_SUCCESS);

	case 'r':
	  mps_context_select_starting_strategy (s, MPS_STARTING_STRATEGY_RECURSIVE);
	  break;

        case 'O':
          /* Select the desired output format */
          if (!opt->optvalue)
            {
              mps_error (s, "An argument is needed for option 'O'");
              break;
            }
          
          switch (*opt->optvalue)
            {
            case 'f':
              mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_FULL);
              break;
            case 'b':
              mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_BARE);
              break;
            case 'g':
              mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_GNUPLOT);
              if (*(opt->optvalue + 1) == 'f')
                {
                  mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_GNUPLOT_FULL);
                  s->gnuplot_format = "xyerrorbars";
                }
              else if (*(opt->optvalue + 1) == 'p')
                {
                  mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_GNUPLOT_FULL);
                  s->gnuplot_format = "points";
                }
              break;
            case 'v':
              mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_VERBOSE);
              break;
            case 'c':
              mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_COMPACT);
              break;
            default:
              mps_error (s, "The selected output format is not supported");
              break;
            }

          break;

            /* select search set */
          case 'S':
            switch (*opt->optvalue)
              {
              case 'a':
                s->output_config->search_set = MPS_SEARCH_SET_COMPLEX_PLANE;
                break;
              case 'r':
                s->output_config->search_set = MPS_SEARCH_SET_POSITIVE_REAL_PART;
                break;
              case 'l':
                s->output_config->search_set = MPS_SEARCH_SET_NEGATIVE_REAL_PART;
                break;
              case 'u':
                s->output_config->search_set = MPS_SEARCH_SET_POSITIVE_IMAG_PART;
                break;
              case 'd':
                s->output_config->search_set = MPS_SEARCH_SET_NEGATIVE_IMAG_PART;
                break;
              case 'i':
                s->output_config->search_set = MPS_SEARCH_SET_UNITARY_DISC;
                break;
              case 'o':
                s->output_config->search_set = MPS_SEARCH_SET_UNITARY_DISC_COMPL;
                break;
              case 'R':
                s->output_config->search_set = MPS_SEARCH_SET_REAL;
                break;
              case 'I':
                s->output_config->search_set = MPS_SEARCH_SET_IMAG;
                break;
              case 'U':
                s->output_config->search_set = MPS_SEARCH_SET_CUSTOM;
                break;
              default:
                mps_error (s, "Bad search set switch: ", opt->optvalue,
                           ", use a|r|l|u|d|i|o|R|I|U");
              }
            if (strlen (opt->optvalue) != 1)
              mps_error (s, "Bad set: ", opt->optvalue);
            break;

            /* select multiplicity */
          case 'M':
            switch (*opt->optvalue)
              {
              case '+':
                s->output_config->multiplicity = true;
                break;
              case '-':
                s->output_config->multiplicity = false;
                break;
              default:
                mps_error (s, "Bad multiplicity switch: ", opt->optvalue,
                           ", use +|-");
              }
            if (strlen (opt->optvalue) != 3)
              mps_error (s, "Bad multiplicity option: ", opt->optvalue);
            break;

            /* detection */
          case 'D':
            switch (*opt->optvalue)
              {
              case 'n':
                s->output_config->root_properties = MPS_OUTPUT_PROPERTY_NONE;
                break;
              case 'r':
                s->output_config->root_properties = MPS_OUTPUT_PROPERTY_REAL;
                break;
              case 'i':
                s->output_config->root_properties = MPS_OUTPUT_PROPERTY_IMAGINARY;
                break;
              case 'b':
                s->output_config->root_properties = MPS_OUTPUT_PROPERTY_REAL | 
                  MPS_OUTPUT_PROPERTY_IMAGINARY;
                break;
              default:
                mps_error (s, "Bad detection switch: ", opt->optvalue,
                           ", use n|r|i|b");
              }
            if (strlen (opt->optvalue) != 1)
              mps_error (s, "Bad detection option: ", opt->optvalue);
            break;

            /* I/O streams */
          case 'R':
            s->rtstr = fopen (opt->optvalue, "r");
            if (s->rtstr == NULL)
              mps_error (s, "Cannot open roots file: ", opt->optvalue);
            s->resume = true;
            break;

            /* Additional checks */
          case 'C':
            switch (*opt->optvalue)
              {
              case 'R':
                s->chkrad = true;
                break;
              case 'r':
                s->chkrad = false;
                break;
              default:
                mps_error (s, "Bad check switch: ", opt->optvalue,
                           ", use R|r");
              }
            if (strlen (opt->optvalue) != 1)
              mps_error (s, "Bad check option: ", opt->optvalue);
            break;

            
        case 'a':
	  explicit_algorithm_selection = true;
          switch (*opt->optvalue)
            {
            case 'u':
              mps_context_select_algorithm (s, MPS_ALGORITHM_STANDARD_MPSOLVE);
              break;
            case 's':
              mps_context_select_algorithm (s, MPS_ALGORITHM_SECULAR_GA);
              break;
            default:
              mps_error (s, "The selected algorithm is not supported");
              break;
            }
          break;
        case 'b':
          mps_context_set_jacobi_iterations (s, true);
          break;
	case 'c':
	  mps_context_set_crude_approximation_mode (s, true);
	  break;
        case 'o':
          mps_context_set_output_prec (s, (atoi (opt->optvalue)) * LOG2_10 + 1);
          break;
        case 'i':
          input_precision = atoi (opt->optvalue) * LOG2_10;
          break;
        case 'G':
          switch (*opt->optvalue)
            {
            case 'a':
              mps_context_set_output_goal (s, MPS_OUTPUT_GOAL_APPROXIMATE);
              break;
            case 'i':
              mps_context_set_output_goal (s, MPS_OUTPUT_GOAL_ISOLATE);
              break;
            case 'c':
              mps_context_set_output_goal (s, MPS_OUTPUT_GOAL_COUNT);
              break;
            default:
              mps_error (s, "The selected goal does not exists");
              break;
            }
          break;

        case 'p':
          inline_poly = strdup (opt->optvalue);
          break;

#ifndef DISABLE_DEBUG
        case 'd':
          mps_context_add_debug_domain (s, MPS_DEBUG_INFO);
          
          if (!opt->optvalue)
            break;

          /* If debugging was enabled, parse debug_level */
          while (*opt->optvalue)
            {         
              char output[255];
              switch (*opt->optvalue++)
                {
                case 't':
                  mps_context_add_debug_domain (s, MPS_DEBUG_TRACE);
                  break;
                case 'a':
                  mps_context_add_debug_domain (s, MPS_DEBUG_APPROXIMATIONS);
                  break;
                case 'c':
                  mps_context_add_debug_domain (s, MPS_DEBUG_CLUSTER);
                  break;
                case 'i':
                  mps_context_add_debug_domain (s, MPS_DEBUG_IMPROVEMENT);
                  break;
                case 'w':
                  mps_context_add_debug_domain (s, MPS_DEBUG_TIMINGS);
                  break;
                case 'o':
                  mps_context_add_debug_domain (s, MPS_DEBUG_IO);
                  break;
                case 'm':
                  mps_context_add_debug_domain (s, MPS_DEBUG_MEMORY);
                  break;
                case 'f':
                  mps_context_add_debug_domain (s, MPS_DEBUG_FUNCTION_CALLS);
                  break;
                case 'p':
                  mps_context_add_debug_domain (s, MPS_DEBUG_PACKETS);
                  break;
                case 'r':
                  mps_context_add_debug_domain (s, MPS_DEBUG_REGENERATION);
                  break;
                default:
                  sprintf (output, "Unrecognized debug option: %c", *(opt->optvalue - 1));
                  mps_error (s, output);
                  break;
                }
            }
          break;
#endif

#if HAVE_GRAPHICAL_DEBUGGER
        case 'x':
          graphic_debug = true;
          break;
#endif          

	case 's':
	  if (opt->optvalue == NULL)
	    {
	      mps_error (s, "You need to specify a valid file with -s");
	      break;
	    }
	  else
	    {
	      s->rtstr = fopen (opt->optvalue, "r");
	      if (! s->rtstr)
		{
		  mps_error (s, "Cannot open the given file: %s", opt->optvalue);
		  break;
		}
	      else
		{
		  mps_context_select_starting_strategy (s, MPS_STARTING_STRATEGY_FILE);
		}
	    }
	  break;

        case 't':
          switch (opt->optvalue[0])
            {
            case 'f':
              phase = float_phase;
              break;
            case 'd':
              phase = dpe_phase;
              break;
            default:
              usage (s, argv[0]);
            }
          break;

        case 'j':
          mps_thread_pool_set_concurrency_limit (s, NULL, atoi (opt->optvalue));
          s->n_threads = atoi (opt->optvalue);
          break;
        default:
          usage (s, argv[0]);
          break;
        }
    }

#if HAVE_GRAPHICAL_DEBUGGER
  if (graphic_debug)
  {
    /* Init GTK only if graphic debug is requested. In all other case is unnecessary
     * and will waste computational time that is likely to bias benchmarks. */
    gtk_init (&argc, &argv);

    logger = mps_iteration_logger_new ();
    mps_iteration_logger_set_mps_context (logger, s);

    g_signal_connect (GTK_WIDGET (logger), "delete_event", 
       G_CALLBACK (on_iteration_logger_destroy), NULL);

    gtk_widget_show_all (GTK_WIDGET (logger));
  }
#endif

  if (mps_context_has_errors (s))
    {
      mps_print_errors (s);
      return EXIT_FAILURE;
    }

  if (argc > 2)
    usage (s, argv[0]);

  /* If no file is provided use standard input */
  if (inline_poly)
    {
      // poly = mps_parse_inline_poly_from_string (s, inline_poly);
      mps_abstract_input_stream * stream = 
       (mps_abstract_input_stream *) mps_memory_file_stream_new (inline_poly);
      poly = mps_monomial_yacc_parser (s, stream);

      if (mps_context_has_errors (s))
       {
         mps_print_errors (s);
         return EXIT_FAILURE;
       }

      free (inline_poly);
    }
  else
    {
      if (argc == 1)
        infile = stdin;
      else
        infile = fopen (argv[1], "r");

      if (!infile)
        {
          mps_error (s, "Cannot open input file for read, aborting.");
          mps_print_errors (s);
          return EXIT_FAILURE;
        }

      /* Parse the input stream and if a polynomial is given as output, 
       * allocate also a secular equation to be used in regeneration */
       poly = mps_parse_stream (s, infile);
     }

  if (!poly)
    {
      mps_error (s, "Error while parsing the polynomial, aborting.");
      mps_print_errors (s);
      return EXIT_FAILURE;
    }
  else
    mps_context_set_input_poly (s, poly);

  /* Override input precision if needed */
  if (input_precision >= 0)
    mps_polynomial_set_input_prec (s, poly, input_precision);

  /* Perform some heuristic for the algorithm selection, but only if the user
   * hasn't explicitely selected one. */
  if (! explicit_algorithm_selection)
    {
      mps_context_select_algorithm (s, (MPS_IS_MONOMIAL_POLY (poly) && 
					MPS_DENSITY_IS_SPARSE (poly->density)) ? 
				    MPS_ALGORITHM_STANDARD_MPSOLVE : MPS_ALGORITHM_SECULAR_GA );
    }

  /* Close the file if it's not stdin */
  if (argc == 2 && ! inline_poly)
    fclose (infile);

  /* Select the starting phase according to user input */
  mps_context_set_starting_phase (s, phase);

  /* Solve the polynomial */
  #if HAVE_GRAPHICAL_DEBUGGER
  if (graphic_debug)
  {
    mps_mpsolve_async (s, cleanup_context, NULL);
    gtk_main ();
  }
  else
  {
  #endif
    mps_mpsolve (s);
    cleanup_context (s, NULL);
  #if HAVE_GRAPHICAL_DEBUGGER
  }
  #endif

}
Esempio n. 2
0
int 
test_mpsolve (char * pol_file, char * res_file, mps_algorithm algorithm)
{
  mpc_t root, ctmp;
  mps_boolean passed = true;
  int i, j, zero_roots = 0;
  char ch;
  rdpe_t eps;

  /* Check the roots */
  FILE* result_stream = fopen (res_file, "r"); 
  FILE* input_stream  = fopen (pol_file, "r");

  if (!result_stream) 
    {
      fprintf (stderr, "Checking \033[1m%-30s\033[0m \033[31;1mno results file found!\033[0m\n", pol_file + 9); 
      return EXIT_FAILURE;
    }
  if (!input_stream)
    {
      fprintf (stderr, "Checking \033[1m%-30s\033[0m \033[31;1mno polinomial file found!\033[0m\n", pol_file + 9); 
      return EXIT_FAILURE;
    }

  /* Create a new empty mps_context */
  mps_context * s = mps_context_new ();

  if (debug)
    mps_context_set_debug_level (s, MPS_DEBUG_TRACE);

  /* Load the polynomial that has been given to us */
  mps_parse_stream (s, input_stream);
  
  fprintf (stderr, "Checking \033[1m%-30s\033[0m [\033[34;1mchecking\033[0m]", pol_file + 9);

  mps_context_set_output_goal (s, MPS_OUTPUT_GOAL_ISOLATE);
  mps_context_set_output_prec (s, 50 * LOG2_10);
  rdpe_set_dl (eps, 1.0, -15);

  /* Solve it */
  mps_context_select_algorithm (s, algorithm);
  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), 53);

  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_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;
            }
        }

      /* printf ("min_dist_%d = ", i); */
      /* rdpe_out_str (stdout, min_dist); */
      /* printf ("\nrad_%d", i); */
      /* rdpe_out_str (stdout, s->drad[i]); */
      /* printf ("\n"); */


      mpc_get_cdpe (cdtmp, mroot[found_root]);
      cdpe_mod (rtmp, cdtmp);
      rdpe_mul_eq (rtmp, eps);
      rdpe_set (exp_drad, rtmp);
      
      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_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;
  
  fclose (input_stream);
  fclose (result_stream);    
  
  mpc_clear (ctmp);   
  mpc_clear (root);
  mpc_vclear (mroot, mps_context_get_degree (s));
  
  free (mroot);
  free (drad);

  if (getenv ("MPS_VERBOSE_TEST") && (strstr (pol_file, getenv ("MPS_VERBOSE_TEST"))))
    {
      mps_context_set_output_format (s, MPS_OUTPUT_FORMAT_GNUPLOT_FULL);
      mps_output (s);
    }

  mps_context_free (s);

  if (passed)
    fprintf (stderr, "\rChecking \033[1m%-30s\033[0m [\033[32;1m  done  \033[0m]\n", pol_file + 9);
  else
    fprintf (stderr, "\rChecking \033[1m%-30s\033[0m [\033[31;1m failed \033[0m]\n", pol_file + 9);

  return passed;
}