예제 #1
0
파일: context.c 프로젝트: akobel/MPSolve
static void
mps_context_init (mps_context * s)
{
  mpf_t test;

  /* Set default streams */
  s->instr = stdin;
  s->outstr = stdout;
  s->logstr = stdout;

  /* Allocate space for the configurations */
  s->input_config = (mps_input_configuration*)mps_malloc (sizeof(mps_input_configuration));
  s->output_config = (mps_output_configuration*)mps_malloc (sizeof(mps_output_configuration));

  mps_set_default_values (s);

  /* Find minimum GMP supported precision */
  mpf_init2 (test, 1);
  s->minimum_gmp_precision = mpf_get_prec (test);
  mpf_clear (test);

  /* Set standard precision */
  s->output_config->prec = (int)(0.9 * DBL_DIG * LOG2_10);
  MPS_DEBUG (s, "Setting prec_out to %ld digits", s->output_config->prec);

  mps_mp_set_prec (s, DBL_DIG * LOG2_10 + 1);

  s->initialized = false;
  s->exit_required = false;
}
예제 #2
0
파일: context.c 프로젝트: akobel/MPSolve
/**
 * @brief Allocate a new mps_context struct with default
 * options.
 */
mps_context *
mps_context_new ()
{
  mps_context * ctx = NULL;

  /* Try to get a low cost context from the factory */
  pthread_mutex_lock (&context_factory_mutex);
  if (context_factory_size > 0)
    {
      /* Pop out a context */
      ctx = context_factory[--context_factory_size];

      if (context_factory_size)
        context_factory = mps_realloc (context_factory,
                                       sizeof(mps_context*) * context_factory_size);
      else
        {
          free (context_factory);
          context_factory = NULL;
        }
    }
  pthread_mutex_unlock (&context_factory_mutex);

  /* Allocate the new mps_context and load default options */
  if (!ctx)
    {
      ctx = (mps_context*)mps_malloc (sizeof(mps_context));
      mps_context_init (ctx);
    }

  return ctx;
}
예제 #3
0
/**
 * @brief Allocate a new mps_context struct with default
 * options.
 */
mps_context *
mps_context_new ()
{
  /* Allocate the new mps_context and load default options */
  mps_context * s = (mps_context*) mps_malloc (sizeof (mps_context));
  mps_context_init (s);
  return s;
}
예제 #4
0
파일: mt.c 프로젝트: akobel/MPSolve
char *
cplx_get_str (char *s, const cplx_t x)
/* output to string as (re , im) */
{
  if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL)
    return NULL;
  sprintf (s, CPLX_OUT_FMT, cplx_Re (x), cplx_Im (x));
  return s;
}
예제 #5
0
void
mps_context_init (mps_context * s)
{
  /* Set default streams */
  s->instr = stdin;
  s->outstr = stdout;
  s->logstr = stdout;

  /* Allocate space for the configurations */
  s->input_config  = (mps_input_configuration  *) mps_malloc (sizeof (mps_input_configuration));
  s->output_config = (mps_output_configuration *) mps_malloc (sizeof (mps_output_configuration));

  mps_set_default_values (s);

  /* Set standard precision */
  s->output_config->prec = (int) (0.9 * DBL_DIG * LOG2_10);
  MPS_DEBUG (s, "Setting prec_out to %ld digits", s->output_config->prec);

  mps_mp_set_prec (s, DBL_DIG * LOG2_10 + 1);

  s->initialized = false;
}
예제 #6
0
파일: mt.c 프로젝트: akobel/MPSolve
char *
rdpe_get_str (char *s, const rdpe_t e)
/* output to string */
{
  double d;
  long int l;

  if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL)
    return NULL;
  rdpe_get_dl (&d, &l, e);
  sprintf (s, RDPE_OUT_FMT, d, l);
  return s;
}
예제 #7
0
파일: mt.c 프로젝트: akobel/MPSolve
char *
cdpe_get_str (char *s, const cdpe_t c)
/* output to string as (re , im) */
{
  double dr, di;
  long int lr, li;

  if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL)
    return NULL;
  rdpe_get_dl (&dr, &lr, cdpe_Re (c));
  rdpe_get_dl (&di, &li, cdpe_Im (c));
  sprintf (s, CDPE_OUT_FMT, dr, lr, di, li);
  return s;
}
예제 #8
0
파일: getopts.c 프로젝트: robol/MPSolve
/**
 * @brief Parse command line options in a similar way of getopts.
 *
 * @param opt_ptr A pointer to a previous used mps_opts that can
 * be re-used, or NULL. If this is NULL it will be allocated.
 * When this function return false the opt_ptr is automatically
 * freed.
 * @param argc_ptr The address in memory of the argc variable
 * obtained by the operating system.
 * @param argv_ptr The address in memory of the argv variable
 * obtained by the operating system.
 * @param opt_format The option that <code>mps_getopts()</code>
 * has to look for. It is passed as a string like
 * <code>"ab:n"</code> where the <code>":"</code> means that the preceding
 * character needs an argument, while single characters not followed
 * by <code>":"</code> don't expect one. In this case a correct call
 * to the program would be
 * @code
 *   ./myprogram -a -n -b 7
 * @endcode
 * or even
 * @code
 *   ./myprogam -a
 * @endcode
 *
 * The option are parsed from argc_ptr and argv_ptr and these
 * are modified taking options away (as the program has been
 * called wihtout these options) so after option parsing the program
 * can still parse other options such as filenames or similar, without
 * worrying about options switch.
 */
mps_boolean
mps_getopts (mps_opt ** opt_ptr, int *argc_ptr, char ***argv_ptr,
             const char *opt_format)
{
  char **argv = *argv_ptr;
  int argc = *argc_ptr;
  char *tmp;
  mps_opt *opt;
  int i, l = strlen (opt_format), steps;

  if ((*opt_ptr) == NULL)
    {
      (*opt_ptr) = (mps_opt*)mps_malloc (sizeof(mps_opt));
    }

  opt = *opt_ptr;

  /* Check if there are other arguments to parse */
  if (!argc)
    {
      free (opt);
      return false;
    }

  if (argc == 1)
    {
      free (opt);
      return false;
    }

  /* Scan for right offset */
  steps = 0;
  while (argv[1][0] != '-')
    {
      /* If we get here then argv[1] is a parameter string
       * that must be preserved, so we should put it on the end
       * of argv. */
      tmp = argv[1];
      for (i = 1; i < argc - 1; i++)
        {
          (*argv_ptr)[i] = argv[i + 1];
        }
      (*argv_ptr)[argc - 1] = tmp;
      steps++;

      /* Check if argc permutation was performed */
      if (steps == argc - 1)
        {
          free (opt);
          return false;
        }
    }


  /* Search argv[0][1] in opt_format */
  for (i = 0; i < l; i++)
    {
      if (opt_format[i] == ':')
        continue;
      else if (argv[1][1] == opt_format[i])
        {
          opt->optchar = opt_format[i];

          /* If there is no argument we are done */
          if (i == l || opt_format[i + 1] != ':')
            {
              opt->optvalue = NULL;
              (*argc_ptr)--;
              (*argv_ptr)[1] = argv[0];
              (*argv_ptr)++;
              return true;
            }

          /* Check if the parameter has an optional argument. If that's the
           * case, don't bother if there are no arguments.
           */
          if (i <= l + 2
              && (opt_format[i + 1] == ':' && opt_format[i + 2] == ':'))
            {
              if (argv[1][2] == '\0')
                {
                  opt->optvalue = NULL;
                  (*argc_ptr)--;
                  (*argv_ptr)[1] = argv[0];
                  (*argv_ptr)++;
                  return true;
                }
            }

          /* If the string is not terminated than we should
           * expect to find the parameter attached to it */
          if (argv[1][2] != '\0')
            {
              if (argv[1][2] == '=')
                {
                  opt->optvalue = argv[1] + 3;
                  (*argc_ptr)--;
                  (*argv_ptr)[1] = argv[0];
                  (*argv_ptr)++;
                  return true;
                }
              else
                {
                  opt->optvalue = argv[1] + 2;
                  (*argc_ptr)--;
                  (*argv_ptr)[1] = argv[0];
                  (*argv_ptr)++;
                  return true;
                }
            }

          /* If the parameter should be in argv[1] but is not
           * there return an error */
          if (argc == 2)
            {
              opt->optvalue = NULL;
              (*argc_ptr)--;
              (*argv_ptr)[1] = argv[0];
              (*argv_ptr)++;
              return true;
            }

          /* Otherwise we can set the argument in the struct */
          opt->optvalue = argv[2];
          (*argc_ptr) -= 2;
          (*argv_ptr)[2] = argv[0];
          (*argv_ptr) += 2;
          return true;
        }
    }

  /* Fallback case, we haven't recognized the input */
  opt->optchar = '?';
  (*argc_ptr)--;
  (*argv_ptr)[1] = argv[0];
  (*argv_ptr)++;

  return true;
}
예제 #9
0
/**
 * @brief Drop-in threaded replacement for the stock mpolzer.
 */
MPS_PRIVATE void
mps_thread_mpolzer (mps_context * s, int *it, mps_boolean * excep, int required_zeros)
{
  int i, nzeros = 0, n_threads = s->n_threads;

  *it = 0;
  *excep = false;

  /* Check if we have already approxmiated roots */
  for (i = 0; i < s->n; i++)
    if (!s->root[i]->again)
      nzeros++;
  if (nzeros == s->n)
    {
      return;
    }

  /* Lower the number of threads if there are a lot of approximated roots */
  if (s->n_threads > (s->n - nzeros))
    n_threads = s->n - nzeros;
  else
    n_threads = s->n_threads;

  MPS_DEBUG_WITH_INFO (s, "Spawning %d worker", n_threads);

  mps_thread_worker_data *data;

  /* Allocate and the init mutexes needed by the routine */
  pthread_mutex_t *roots_mutex =
    (pthread_mutex_t*)mps_malloc (sizeof(pthread_mutex_t) * s->n);
  pthread_mutex_t *aberth_mutex =
    (pthread_mutex_t*)mps_malloc (sizeof(pthread_mutex_t) * s->n);
  pthread_mutex_t global_aberth_mutex = PTHREAD_MUTEX_INITIALIZER;

  for (i = 0; i < s->n; i++)
    {
      pthread_mutex_init (&aberth_mutex[i], NULL);
      pthread_mutex_init (&roots_mutex[i], NULL);
    }

  /* Create a new work queue */
  mps_thread_job_queue *queue = mps_thread_job_queue_new (s);

  data = (mps_thread_worker_data*)mps_malloc (sizeof(mps_thread_worker_data)
                                              * n_threads);

  /* Set data to be passed to every thread and actually spawn the threads. */
  for (i = 0; i < n_threads; i++)
    {
      data[i].it = it;
      data[i].nzeros = &nzeros;
      data[i].s = s;
      data[i].excep = excep;
      data[i].thread = i;
      data[i].n_threads = n_threads;
      data[i].aberth_mutex = aberth_mutex;
      data[i].global_aberth_mutex = &global_aberth_mutex;
      data[i].queue = queue;
      data[i].roots_mutex = roots_mutex;
      data[i].required_zeros = required_zeros;
      mps_thread_pool_assign (s, s->pool, mps_thread_mpolzer_worker, data + i);
    }

  /* Wait for the threads to complete */
  mps_thread_pool_wait (s, s->pool);

  /* Free data and exit */
  free (data);
  for (i = 0; i < s->n; i++)
    {
      pthread_mutex_destroy (&roots_mutex[i]);
      pthread_mutex_destroy (&aberth_mutex[i]);
    }
  free (roots_mutex);
  free (aberth_mutex);
  mps_thread_job_queue_free (queue);
}
예제 #10
0
/**
 * @brief Multithread version of mps_dpolzer ().
 */
MPS_PRIVATE void
mps_thread_dpolzer (mps_context * s, int *it, mps_boolean * excep, int required_zeros)
{
  mps_thread_worker_data *data;
  pthread_mutex_t *aberth_mutex, *roots_mutex;
  int i, nzeros = 0;

  /* initialize the iteration counter */
  *it = 0;
  *excep = false;

  /* count the number of approximations in the root neighbourhood */
  for (i = 0; i < s->n; i++)
    if (!s->root[i]->again)
      nzeros++;
  if (nzeros == s->n)
    return;

  /* Prepare queue */
  mps_thread_job_queue *queue = mps_thread_job_queue_new (s);

  /* Allocate space for thread data */
  data = (mps_thread_worker_data*)mps_malloc (sizeof(mps_thread_worker_data)
                                              * s->n_threads);

  /* Allocate mutexes and init them */
  aberth_mutex = (pthread_mutex_t*)mps_malloc (sizeof(pthread_mutex_t) * s->n);
  roots_mutex = (pthread_mutex_t*)mps_malloc (sizeof(pthread_mutex_t) * s->n);
  for (i = 0; i < s->n; i++)
    {
      if (s->pool->n > 1)
	{
	  pthread_mutex_init (&aberth_mutex[i], NULL);
	  pthread_mutex_init (&roots_mutex[i], NULL);
	}
    }

  /* Start spawning thread */
  for (i = 0; i < s->n_threads; i++)
    {
      data[i].aberth_mutex = aberth_mutex;
      data[i].excep = excep;
      data[i].it = it;
      data[i].n_threads = s->n_threads;
      data[i].nzeros = &nzeros;
      data[i].queue = queue;
      data[i].roots_mutex = roots_mutex;
      data[i].s = s;
      data[i].thread = i;
      data[i].required_zeros = required_zeros;
      mps_thread_pool_assign (s, s->pool, mps_thread_dpolzer_worker, data + i);
    }

  /* Wait for the thread to complete */
  mps_thread_pool_wait (s, s->pool);

  free (aberth_mutex);
  free (roots_mutex);
  free (data);
  mps_thread_job_queue_free (queue);
}
예제 #11
0
/**
 * @brief Drop-in replacement for the stock fpolzer routine.
 * This version adds multithread support.
 */
MPS_PRIVATE void
mps_thread_fpolzer (mps_context * s, int *it, mps_boolean * excep, int required_zeros)
{
  int i, nzeros = 0, n_threads = s->n_threads;

  mps_thread_worker_data *data;
  pthread_mutex_t *aberth_mutex =
    (pthread_mutex_t*)mps_malloc (sizeof(pthread_mutex_t) * s->n);
  pthread_mutex_t *roots_mutex =
    (pthread_mutex_t*)mps_malloc (sizeof(pthread_mutex_t) * s->n);

  for (i = 0; i < s->n; i++)
    {
      pthread_mutex_init (roots_mutex + i, NULL);
      pthread_mutex_init (aberth_mutex + i, NULL);
    }

  /* Create a new job queue */
  mps_thread_job_queue *queue = mps_thread_job_queue_new (s);

  *it = 0;
  *excep = false;

  /* count the number of approximations in the root neighbourhood */
  for (i = 0; i < s->n; i++)
    if (!s->root[i]->again)
      nzeros++;
  if (nzeros == s->n)
    {
      free (roots_mutex);
      free (aberth_mutex);
      mps_thread_job_queue_free (queue);
      return;
    }

  data = (mps_thread_worker_data*)mps_malloc (sizeof(mps_thread_worker_data)
                                              * n_threads);

  for (i = 0; i < n_threads; i++)
    {
      data[i].it = it;
      data[i].nzeros = &nzeros;
      data[i].s = s;
      data[i].excep = excep;
      data[i].thread = i;
      data[i].n_threads = n_threads;
      data[i].aberth_mutex = aberth_mutex;
      data[i].roots_mutex = roots_mutex;
      data[i].queue = queue;
      data[i].required_zeros = required_zeros;
      /* pthread_create (&threads[i], NULL, &mps_thread_fpolzer_worker, */
      /* data + i); */
      mps_thread_pool_assign (s, s->pool, mps_thread_fpolzer_worker, data + i);
    }

  mps_thread_pool_wait (s, s->pool);

  free (data);
  free (roots_mutex);
  free (aberth_mutex);
  mps_thread_job_queue_free (queue);
}