Быстро трансцендентный / тригонометрические функции для Java

Я использую несколько иной подход при попытке получить данные из datagridview.

Попробуйте выполнить personIDTextBox.Text = DataGridView01.SelectedCells[0].Value.ToString();

, но вместо того, чтобы событие было на смене выбора, переключитесь на CellClick и изменить свойство свойства выбора строки datagridview для выбора полной строки. после этого вы можете изменить номер SelectedCell[0], чтобы соответствовать любой ячейке, которую вы хотите

19
задан 4 revs 8 February 2009 в 21:27
поделиться

12 ответов

Компьютерные Приближения Hart. Сводит в таблицу сэкономленный Чебышевыми приближенные формулы для набора функций в различной точности.

Редактирование: Получение моей копии с полки, это оказалось другая книга , которая просто звучит очень похожей. Вот является функция греха использованием ее таблиц. (Протестированный в C, так как это более удобно для меня.) Я не знаю, будет ли это быстрее, чем встроенный Java, но он, как гарантируют, будет менее точным, по крайней мере.:) Вы, возможно, должны расположиться - уменьшают аргумент сначала; см. предложения John Cook . Книга также имеет arcsin и arctan.

#include <math.h>
#include <stdio.h>

// Return an approx to sin(pi/2 * x) where -1 <= x <= 1.
// In that range it has a max absolute error of 5e-9
// according to Hastings, Approximations For Digital Computers.
static double xsin (double x) {
  double x2 = x * x;
  return ((((.00015148419 * x2
             - .00467376557) * x2
            + .07968967928) * x2
           - .64596371106) * x2
          + 1.57079631847) * x;
}

int main () {
  double pi = 4 * atan (1);
  printf ("%.10f\n", xsin (0.77));
  printf ("%.10f\n", sin (0.77 * (pi/2)));
  return 0;
}
15
ответ дан 30 November 2019 в 03:08
поделиться

Здесь набор приемов низкого уровня для того, чтобы быстро приблизить аккуратные функции. Существует пример кода в C, который я нахожу трудно для следования, но методы столь же легко реализованы в Java.

Вот моя эквивалентная реализация invsqrt и atan2 в Java.

я, возможно, сделал что-то подобное для других аккуратных функций, но я не считал это необходимым, поскольку профилирование показало, что только sqrt и atan/atan2 были главными узкими местами.

public class FastTrig
{
  /** Fast approximation of 1.0 / sqrt(x).
   * See <a href="http://www.beyond3d.com/content/articles/8/">http://www.beyond3d.com/content/articles/8/</a>
   * @param x Positive value to estimate inverse of square root of
   * @return Approximately 1.0 / sqrt(x)
   **/
  public static double
  invSqrt(double x)
  {
    double xhalf = 0.5 * x; 
    long i = Double.doubleToRawLongBits(x);
    i = 0x5FE6EB50C7B537AAL - (i>>1); 
    x = Double.longBitsToDouble(i);
    x = x * (1.5 - xhalf*x*x); 
    return x; 
  }

  /** Approximation of arctangent.
   *  Slightly faster and substantially less accurate than
   *  {@link Math#atan2(double, double)}.
   **/
  public static double fast_atan2(double y, double x)
  {
    double d2 = x*x + y*y;

    // Bail out if d2 is NaN, zero or subnormal
    if (Double.isNaN(d2) ||
        (Double.doubleToRawLongBits(d2) < 0x10000000000000L))
    {
      return Double.NaN;
    }

    // Normalise such that 0.0 <= y <= x
    boolean negY = y < 0.0;
    if (negY) {y = -y;}
    boolean negX = x < 0.0;
    if (negX) {x = -x;}
    boolean steep = y > x;
    if (steep)
    {
      double t = x;
      x = y;
      y = t;
    }

    // Scale to unit circle (0.0 <= y <= x <= 1.0)
    double rinv = invSqrt(d2); // rinv ≅ 1.0 / hypot(x, y)
    x *= rinv; // x ≅ cos θ
    y *= rinv; // y ≅ sin θ, hence θ ≅ asin y

    // Hack: we want: ind = floor(y * 256)
    // We deliberately force truncation by adding floating-point numbers whose
    // exponents differ greatly.  The FPU will right-shift y to match exponents,
    // dropping all but the first 9 significant bits, which become the 9 LSBs
    // of the resulting mantissa.
    // Inspired by a similar piece of C code at
    // http://www.shellandslate.com/computermath101.html
    double yp = FRAC_BIAS + y;
    int ind = (int) Double.doubleToRawLongBits(yp);

    // Find φ (a first approximation of θ) from the LUT
    double φ = ASIN_TAB[ind];
    double cφ = COS_TAB[ind]; // cos(φ)

    // sin(φ) == ind / 256.0
    // Note that sφ is truncated, hence not identical to y.
    double sφ = yp - FRAC_BIAS;
    double sd = y * cφ - x * sφ; // sin(θ-φ) ≡ sinθ cosφ - cosθ sinφ

    // asin(sd) ≅ sd + ⅙sd³ (from first 2 terms of Maclaurin series)
    double d = (6.0 + sd * sd) * sd * ONE_SIXTH;
    double θ = φ + d;

    // Translate back to correct octant
    if (steep) { θ = Math.PI * 0.5 - θ; }
    if (negX) { θ = Math.PI - θ; }
    if (negY) { θ = -θ; }

    return θ;
  }

  private static final double ONE_SIXTH = 1.0 / 6.0;
  private static final int FRAC_EXP = 8; // LUT precision == 2 ** -8 == 1/256
  private static final int LUT_SIZE = (1 << FRAC_EXP) + 1;
  private static final double FRAC_BIAS =
    Double.longBitsToDouble((0x433L - FRAC_EXP) << 52);
  private static final double[] ASIN_TAB = new double[LUT_SIZE];
  private static final double[] COS_TAB = new double[LUT_SIZE];

  static
  {
    /* Populate trig tables */
    for (int ind = 0; ind < LUT_SIZE; ++ ind)
    {
      double v = ind / (double) (1 << FRAC_EXP);
      double asinv = Math.asin(v);
      COS_TAB[ind] = Math.cos(asinv);
      ASIN_TAB[ind] = asinv;
    }
  }
}
13
ответ дан 30 November 2019 в 03:08
поделиться

Я удивлен, что встроенные функции Java были бы настолько медленными. Конечно, JVM вызывает собственные аккуратные функции на Вашем ЦП, не реализовывая алгоритмы в Java. Вы уверены, что Ваше узкое место является вызовами к аккуратным функциям и не некоторому окружающему коду? Возможно, некоторые выделения памяти?

Вы могли переписать в C++ часть своего кода, который делает математику? Просто вызов кода C++ для вычислений аккуратных функций, вероятно, не ускорил бы вещи, но перемещающий некоторый контекст также, как внешний цикл, к C++ мог бы ускорить вещи.

, Если необходимо прокрутить собственные аккуратные функции, не используйте один только Ряд Тейлора. Алгоритмы CORDIC намного быстрее, если Ваш аргумент не является очень маленьким. Вы могли использовать CORDIC для начала работы, затем полировать результат с коротким Рядом Тейлора. Посмотрите этот вопрос о StackOverflow на , как реализовать аккуратные функции .

4
ответ дан 30 November 2019 в 03:08
поделиться

На x86 java.lang. Математический грех и потому что функции непосредственно не называют аппаратные функции, потому что Intel не всегда делал такое хорошее задание, реализовывая их. Существует хорошее объяснение в ошибке № 4857011.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4857011

, Вы могли бы хотеть думать трудно о неточном результате. Забавно, как часто я провожу время, находя это в коде других.

, "Но комментарий говорит Грех..."

4
ответ дан 30 November 2019 в 03:08
поделиться

Вы могли предварительно сохранить свой грех и потому что в массиве, если Вам только нужны некоторые приближенные значения. Например, если Вы хотите сохранить значения от 0В ° до 360В °:

double sin[]=new double[360];
for(int i=0;i< sin.length;++i) sin[i]=Math.sin(i/180.0*Math.PI):

Вы затем используете этот массив с помощью градусов/целых чисел вместо радианов / двойной.

2
ответ дан 30 November 2019 в 03:08
поделиться

Я не услышал ни о ком, освобождает, вероятно, потому что достаточно редко видеть аккуратные тяжелые приложения Java. Это также достаточно легко к самокрутке с JNI (та же точность, лучшая производительность), численные методы (переменная точность / производительность) или простая таблица приближения.

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

1
ответ дан 30 November 2019 в 03:08
поделиться

Тригонометрические функции являются классическим примером для справочной таблицы. Посмотрите превосходное

при поиске библиотеки J2ME, можно попробовать:

  • Целочисленная Математическая Библиотека Фиксированной точки MathFP
1
ответ дан 30 November 2019 в 03:08
поделиться

java.lang. Математические функции называют аппаратные функции. Должен быть простой appromiations, который можно сделать, но они не будут так же точны.

На моем labtop, грешите и потому что берет приблизительно 144 нс.

0
ответ дан 30 November 2019 в 03:08
поделиться

В тесте sin/cos я выполнял для целочисленного нуля к один миллион. Я предполагаю, что 144 нс не достаточно быстры для Вас.

у Вас есть конкретное требование для скорости, в которой Вы нуждаетесь?

можно ли квалифицировать требование с точки зрения времени на операцию, которая является удовлетворительной?

0
ответ дан 30 November 2019 в 03:08
поделиться

Выезд Apache Математический пакет палаты общин , если Вы хотите использовать существующий материал.

, Если производительность действительно существенная, то можно пойти о реализации этих функций сами с помощью стандартных математических методов - серия Taylor/Maclaurin, конкретно.

, Например, вот несколько расширений Ряда Тейлора, которые могли бы быть полезными (взятый от Википедия ):

alt text

alt text

alt text

-1
ответ дан 30 November 2019 в 03:08
поделиться

Могли Вы уточнять то, что необходимо сделать, если эти стандартные программы являются слишком медленными. Вы смогли делать некоторые координатные преобразования заранее некоторый путь или другой.

-1
ответ дан 30 November 2019 в 03:08
поделиться

Это могло бы сделать это: http://sourceforge.net/projects/jafama/

5
ответ дан 30 November 2019 в 03:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: