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?