Exemple #1
0
void
mps_maberth_s_wl (mps_context * s, int j, mps_cluster * cluster, mpc_t abcorr,
                  pthread_mutex_t * aberth_mutexes)
{
  int k;
  mps_root * root;
  cdpe_t z, temp;
  mpc_t diff, mroot;
  
  mpc_init2 (mroot, s->mpwp);
  mpc_init2 (diff, s->mpwp);

  pthread_mutex_lock (&aberth_mutexes[j]);
  mpc_set (mroot, s->root[j]->mvalue);
  pthread_mutex_unlock (&aberth_mutexes[j]);

  cdpe_set (temp, cdpe_zero);
  for (root = cluster->first; root != NULL; root = root->next)
    {
      k = root->k;
      if (k == j)
        continue;

      pthread_mutex_lock (&aberth_mutexes[k]);
      mpc_sub (diff, mroot, s->root[k]->mvalue);
      pthread_mutex_unlock (&aberth_mutexes[k]);
      mpc_get_cdpe (z, diff);

      if (cdpe_eq_zero(z))
        continue;

      cdpe_inv_eq (z);
      cdpe_add_eq (temp, z);
    }
  mpc_set_cdpe (abcorr, temp);

  mpc_clear (mroot);
  mpc_clear (diff);
}
Exemple #2
0
/**
 * @brief Multithread worker for mps_thread_dpolzer ()
 */
static void *
mps_thread_dpolzer_worker (void *data_ptr)
{
  int iter, i;
  rdpe_t rad1, rtmp;
  cdpe_t corr, abcorr;

  /* Parse input data */
  mps_thread_worker_data *data = (mps_thread_worker_data*)data_ptr;
  mps_context *s = data->s;
  mps_polynomial *p = s->active_poly;
  mps_thread_job job;

  while (!(*data->excep) && (*data->nzeros < data->required_zeros))
    {
      job = mps_thread_job_queue_next (s, data->queue);
      i = job.i;
      iter = job.iter;

      /* Check if we got over the maximum number of iterations */
      if (job.iter == MPS_THREAD_JOB_EXCEP)
        {
          (*data->excep) = true;
          return 0;
        }

      /* Make sure that we are the only one iterating on this root */
      if (s->pool->n > 1)
	pthread_mutex_lock (&data->roots_mutex[i]);

      if (s->root[i]->again)
        {
          /* Check if, while we were waiting, excep condition has been reached */
          if (*data->excep || !s->root[i]->again || (*data->nzeros > data->required_zeros))
            {
	      if (s->pool->n > 1)
		pthread_mutex_unlock (&data->roots_mutex[i]);
              return 0;
            }

          (*data->it)++;
          rdpe_set (rad1, s->root[i]->drad);

          mps_polynomial_dnewton (s, p, s->root[i], corr);
          if (iter == 0 && !s->root[i]->again && rdpe_gt (s->root[i]->drad, rad1)
              && rdpe_ne (rad1, rdpe_zero))
            rdpe_set (s->root[i]->drad, rad1);
          /************************************************
             The above condition is needed to manage with the case where
             at the first iteration the starting point is already in the
             root neighbourhood and the actually computed radius is too
             big since the value of the first derivative is too small.
             In this case the previous radius bound, obtained by means of
             Rouche' is more reliable and strict
           **********************************************/

          if (s->root[i]->again
              /* the correction is performed only if iter!=1 or rad(i)!=rad1 */
              || iter != 0
              || rdpe_ne (s->root[i]->drad, rad1))
            {
              mps_daberth (s, s->root[i], abcorr);
              cdpe_mul_eq (abcorr, corr);
              cdpe_sub (abcorr, cdpe_one, abcorr);
              if (cdpe_eq_zero (abcorr))
                {
                  MPS_DEBUG (s, "Aberth correction is zero.");
                  s->lastphase = dpe_phase;
                  cdpe_set_d (abcorr, DBL_EPSILON, 0);
                }

              cdpe_div (abcorr, corr, abcorr);
              cdpe_sub_eq (s->root[i]->dvalue, abcorr);
              cdpe_mod (rtmp, abcorr);
              rdpe_add_eq (s->root[i]->drad, rtmp);
            }

          /* check for new approximated roots */
          if (!s->root[i]->again)
            {
              (*data->nzeros)++;
              if ((*data->nzeros) >= data->required_zeros)
                {
		  if (s->pool->n > 1)
		    pthread_mutex_unlock (&data->roots_mutex[i]);
                  return 0;
                }
            }
        }

      if (s->pool->n > 1)
	pthread_mutex_unlock (&data->roots_mutex[i]);
    }

  return NULL;
}