четверг, 27 августа 2009 г.

Приближённое вычисление функции arctg(x)

Не стал бы публиковать данное сообщение в блоге, если бы не один забавный факт.

Оказывается не для всех метрик приближение с использованием сплайнов даёт лучший результат. Например, приближение функции арктангенс на отрезке [0, 1] одним отрезком спалайна оказалось менее оптимальным, чем приближение некоторым другим многочленом третьей степени. Один из таких многочленов используется в следующем примере.

Когда мы приближаем данную функцию многочленом третьей степени, то погрешность такого приближения можно найти аналитически.

/**
 * Реализация функции arctg(x)
 * (погрешность на отрезке [0, 1] не более .00652- радиана)
 */
double atanImpl(double x)
{
  return (((-0.076413) * x + (-0.13167)) * x + 1) * x;
}

/**
 * Реализация функции atan2
 */
double atan2(double y, double x)
{
  if (y >= 0.0) {
    if (x >= 0.0) {
      if (x >= y) {
        return atanImpl(y / x);
      } else {
        return ONE_HALF_PI - atanImpl(x / y);
    } else {
      x = -x;
      if (x < y) {
        return ONE_HALF_PI + atanImpl(x / y);
      } else {
        return PI - atanImpl(y / x);
      }
    } else {
      if (x <= 0.0) {
        if (x <= y) {
          return - PI + atanImpl(y / x);
        } else {
          return - ONE_HALF_PI - atanImpl(x / y);
        }
      } else {
        x = -x;
        if (x > y) {
          return - ONE_HALF_PI + atanImpl(x / y);
        } else {
          return - atanImpl(y / x);
        }
      }
    }
  }
}

UPD:
/**
 * Реализация функции arctg(x)
 * (погрешность на отрезке [0, 1] не более .0049- радиана)
 * http://www.autex.spb.ru/download/...
 *                     .../dsp/dspa/dspa2006/t1/1-42.pdf
 */
double atanImpl(double x)
{
  return (32 * x) / (32 + 9 * x * x);
}

UPD2: Математическая запись тех же формул.

Комментариев нет: