Math-Cephes

 view release on metacpan or  search on metacpan

libmd/polmisc.c  view on Meta::CPAN

  int i, n;
#if 0
  double z[N+1];
  double u;
#endif

  if (nn > N)
    {
      mtherr ("polatn", OVERFLOW);
      return;
    }
  x = (double * )malloc( (MAXPOL+1) * sizeof (double) );
  y = (double * )malloc( (MAXPOL+1) * sizeof (double) );
  polmov( pol, nn, x );
  polclr( y, MAXPOL );

  /* Find lowest degree nonzero term.  */
  t = 0.0;
  for( n=0; n<nn; n++ )
    {
      if( x[n] != 0.0 )
	goto nzero;
    }
  polmov( y, nn, ans );
  return;

nzero:

  if( n > 0 )
    {
      if (n & 1)
        {
	  printf("error, sqrt of odd polynomial\n");
	  return;
	}
      /* Divide by x^n.  */
      y[n] = x[n];
      poldiv (y, nn, pol, N, x);
    }

  t = x[0];
  for( i=1; i<=nn; i++ )
    x[i] /= t;
  x[0] = 0.0;
  /* series development sqrt(1+x) = 1  +  x / 2  -  x**2 / 8  +  x**3 / 16
     hopes that first (constant) term is greater than what follows   */
  polsbt( x, nn, psqrt, nn, y);
  t = sqrt( t );
  for( i=0; i<=nn; i++ )
    y[i] *= t;

  /* If first nonzero coefficient was at degree n > 0, multiply by
     x^(n/2).  */
  if (n > 0)
    {
      polclr (x, MAXPOL);
      x[n/2] = 1.0;
      polmul (x, nn, y, nn, y);
    }
#if 0
/* Newton iterations */
for( n=0; n<10; n++ )
	{
	poldiv( y, nn, pol, nn, z );
	poladd( y, nn, z, nn, y );
	for( i=0; i<=nn; i++ )
		y[i] *= 0.5;
	for( i=0; i<=nn; i++ )
		{
		u = md_fabs( y[i] - z[i] );
		if( u > 1.0e-15 )
			goto more;
		}
	goto done;
more:	;
	}
printf( "square root did not converge\n" );
done:
#endif /* 0 */

polmov( y, nn, ans );
free( y );
free( x );
}



/* Sine of a polynomial.
 * The computation uses
 *     md_sin(a+b) = md_sin(a) md_cos(b) + md_cos(a) md_sin(b)
 * where a is the constant term of the polynomial and
 * b is the sum of the rest of the terms.
 * Since md_sin(b) and md_cos(b) are computed by series expansions,
 * the value of b should be small.
 */
void
polsin( x, y, nn )
     double x[], y[];
     int nn;
{
  double a, sc;
  double *w, *c;
  int i;

  if (nn > N)
    {
      mtherr ("polatn", OVERFLOW);
      return;
    }
  w = (double * )malloc( (MAXPOL+1) * sizeof (double) );
  c = (double * )malloc( (MAXPOL+1) * sizeof (double) );
  polmov( x, nn, w );
  polclr( c, MAXPOL );
  polclr( y, nn );
  /* a, in the description, is x[0].  b is the polynomial x - x[0].  */
  a = w[0];
  /* c = md_cos (b) */
  w[0] = 0.0;
  polsbt( w, nn, pcos, nn, c );
  sc = md_sin(a);
  /* md_sin(a) md_cos (b) */



( run in 0.570 second using v1.01-cache-2.11-cpan-71847e10f99 )