예제 #1
0
파일: aberth.c 프로젝트: jasongrout/mpsolve
/**
 * @brief Compute Aberth correction for j-th root, without
 * selective correction.
 */
void
mps_daberth (mps_context * s, mps_approximation * root, cdpe_t abcorr)
{
  int i;
  cdpe_t z;

  cdpe_set (abcorr, cdpe_zero);
  for (i = 0; i < s->n; i++)
    {
      if (s->root[i] == root)
        continue;
      cdpe_sub (z, root->dvalue, s->root[i]->dvalue);
      cdpe_inv_eq (z);
      cdpe_add_eq (abcorr, z);
    }
}
예제 #2
0
파일: aberth.c 프로젝트: jasongrout/mpsolve
/**
 * @brief Compute Aberth correction for the j-th root,
 * but only with other roots of the <code>jc</code>-th
 * cluster.
 */
void
mps_daberth_s (mps_context * s, mps_approximation * ab_root, mps_cluster * cluster, cdpe_t abcorr)
{
  mps_root * root;
  cdpe_t z;

  cdpe_set (abcorr, cdpe_zero);
  for (root = cluster->first; root != NULL; root = root->next)
    {
      mps_approximation * appr = s->root[root->k];
      if (appr == ab_root)
        continue;
      cdpe_sub (z, ab_root->dvalue, appr->dvalue);
      cdpe_inv_eq (z);
      cdpe_add_eq (abcorr, z);
    }
}
예제 #3
0
파일: aberth.c 프로젝트: jasongrout/mpsolve
void
mps_daberth_wl (mps_context * s, int j, cdpe_t abcorr, pthread_mutex_t * aberth_mutexes)
{
  int i;
  cdpe_t z, droot;

  pthread_mutex_lock (&aberth_mutexes[j]);
  cdpe_set (droot, s->root[j]->dvalue);
  pthread_mutex_unlock (&aberth_mutexes[j]);

  cdpe_set (abcorr, cdpe_zero);
  for (i = 0; i < s->n; i++)
    {
      if (i == j)
        continue;

      pthread_mutex_lock (&aberth_mutexes[i]);
      cdpe_sub (z, droot, s->root[i]->dvalue);
      pthread_mutex_unlock (&aberth_mutexes[i]);

      cdpe_inv_eq (z);
      cdpe_add_eq (abcorr, z);
    }
}
예제 #4
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;
}