Implementación de sinpi () y cospi () usando la biblioteca matemática C estándar

La funciónsinpi(x) calcula sin (πx) y la funcióncospi(x) calcula cos (πx), donde la multiplicación con π está implícita dentro de las funciones. Estas funciones se introdujeron inicialmente en la biblioteca matemática estándar C como una extensión de Sun Microsystems en elfinales de los 80. IEEE Std 754 ™ -2008 especifica las funciones equivalentessinPi ycosPi en la sección 9.

Existen numerosos cálculos donde sin (πx) y cos (πx) ocurren naturalmente. Un ejemplo muy simple es la transformación Box-Muller (G. E. P. Box y Mervin E. Muller, "Una nota sobre la generación de desviaciones normales aleatorias".Los anales de la estadística matemáticaVol. 29, N ° 2, págs. 610 - 611), que, dadas dos variables aleatorias independientes U₁ y U₂ con distribución uniforme, produce variables aleatorias independientes Z₁ y Z₂ con distribución normal estándar:

Z₁ = √(-2 ln U₁) cos (2 π U₂)
Z₂ = √(-2 ln U₁) sin (2 π U₂)

Otro ejemplo es el cálculo del seno y el coseno para los argumentos de grado, como en este cálculo de la distancia del gran círculo utilizando la fórmula de Haversine:

/* This function computes the great-circle distance of two points on earth 
   using the Haversine formula, assuming spherical shape of the planet. A 
   well-known numerical issue with the formula is reduced accuracy in the 
   case of near antipodal points.

   lat1, lon1  latitude and longitude of first point, in degrees [-90,+90]
   lat2, lon2  latitude and longitude of second point, in degrees [-180,+180]
   radius      radius of the earth in user-defined units, e.g. 6378.2 km or 
               3963.2 miles

   returns:    distance of the two point,s, in the same units as radius

   Reference: http://en.wikipedia.org/wiki/Great-circle_distance
*/
double haversine (double lat1, double lon1, double lat2, double lon2, double radius)
{
    double dlat, dlon, c1, c2, d1, d2, a, c, t;

    c1 = cospi (lat1 / 180.0);
    c2 = cospi (lat2 / 180.0);
    dlat = lat2 - lat1;
    dlon = lon2 - lon1;
    d1 = sinpi (dlat / 360.0);
    d2 = sinpi (dlon / 360.0);
    t = d2 * d2 * c1 * c2;
    a = d1 * d1 + t;
    c = 2.0 * asin (fmin (1.0, sqrt (a)));
    return radius * c;
}

Para C ++, la biblioteca Boost proporcionasin_pi ycos_pi, y algunos proveedores ofrecensinpi ycospi funcionalidad como extensiones en bibliotecas del sistema. Por ejemplo, Apple agregó__sinpi, __cospi y las correspondientes versiones de precisión simple__sinpif, __cospif a iOS 7 y OS X 10.9 (presentación, diapositiva 101). Pero para muchas otras plataformas, no existe una implementación fácilmente accesible para los programas en C.

En comparación con un enfoque tradicional que utiliza, p.sin (M_PI * x) ycos (M_PI * x), el uso desinpi ycospi mejora la precisión al reducir el error de redondeo a través deinterno multiplicación con π, y también ofrece ventajas de rendimiento debido a la reducción de argumento mucho más simple.

¿Cómo se puede usar la biblioteca matemática C estándar para implementarsinpi() ycospi() Funcionalidad de una manera razonablemente eficiente y conforme a la norma?

Respuestas a la pregunta(1)

Su respuesta a la pregunta