Численные вычисления в Java - PullRequest
1 голос
/ 04 декабря 2009

Хорошо, поэтому я пытаюсь использовать библиотеку Apache Commons Math для вычисления двойного интеграла, но они оба имеют отрицательную бесконечность (примерно до 1), и для вычисления требуются целые века. Есть ли другие способы сделать такие операции в Java? Или он должен работать «быстрее» (я имею в виду, что смогу увидеть результат за день до смерти), и я делаю что-то не так?

РЕДАКТИРОВАТЬ: Хорошо, спасибо за ответы. Что касается того, что я пытался вычислить, это гауссовская копула: alt text

Таким образом, у нас есть стандартная двумерная нормальная кумулятивная функция распределения, которая принимает в качестве аргументов две обратных стандартных нормальных кумулятивных функции распределения, и мне нужны целые числа для вычисления этого (я знаю, что есть функция Apache Commons Math для стандартного нормального кумулятивного распределения, но мне не удалось найти обратная и двумерная версии).

РЕДАКТИРОВАТЬ2: как мой друг однажды сказал: «Аааа, да, красота Java, независимо от того, что вы хотите сделать, кто-то уже сделал это», я нашел здесь все, что мне было нужно http://www.iro.umontreal.ca/~simardr/ssj/ очень хорошая библиотека для вероятности и т. Д. .

Ответы [ 4 ]

2 голосов
/ 05 декабря 2009

Есть две проблемы с бесконечными интегралами: сходимость и значение сходимости. То есть интеграл сходится? Если да, то к какому значению это сходится? Существуют интегралы, которые гарантированно сходятся, но их значение невозможно точно определить (попробуйте интеграл от 1 до бесконечности e ^ (- x ^ 2)). Если это не может быть точно возвращено, то точный ответ не возможен математически, который оставляет только приближение. Apache Commons использует несколько различных схем аппроксимации, но все они требуют использования конечных границ для корректности.

Лучший способ получить соответствующий ответ - многократно оценивать конечные интегралы с постоянно растущими границами и сравнивать результаты. В псевдокоде это будет выглядеть примерно так:

double DELTA = 10^-6//your error threshold here
double STEP_SIZE = 10.0;
double oldValue=Double.MAX_VALUE;
double newValue=oldValue;
double lowerBound=-10; //or whatever you want to start with--for (-infinity,1), I'd
                       //start with something like -10
double upperBound=1;

do{
     oldValue = newValue;

     lowerBound-= STEP_SIZE;
     newValue = integrate(lowerBound,upperBound); //perform your integration methods here
}while(Math.abs(newValue-oldValue)>DELTA);

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

Хотя слово для мудрых: такого рода вещи могут быть чрезвычайно плохими, если интеграл не сходится. В этом случае может возникнуть одна из двух ситуаций: либо условие завершения никогда не выполняется, и вы попадаете в бесконечный цикл, либо значение интеграла колеблется бесконечно вокруг значения, что может привести к неправильному выполнению условия завершения (давая неверные результаты).

Чтобы избежать первого, лучший способ - ввести максимальное количество шагов, которые необходимо выполнить перед возвратом - это должно остановить потенциально бесконечный цикл, который может привести к этому.

Чтобы избежать второго, надейтесь, что этого не произойдет, или докажите, что интеграл должен сходиться (три ура для Calculus 2, кто-нибудь?; -)).

Чтобы ответить на ваш вопрос формально, нет, нет других подобных способов выполнить ваши вычисления в Java. На самом деле, нет никаких гарантированных способов сделать это на любом языке, с любым алгоритмом - математика просто не работает так, как мы этого хотим. Однако на практике многие (хотя и не все!) Практических интегралов сходятся; По моему опыту, всего около ~ 20 итераций даст вам приблизительную точность, и Apache должен быть достаточно быстрым, чтобы справиться с этим, не занимая до абсурда много времени.

2 голосов
/ 05 декабря 2009

Предположим, что вы интегрируете f (x) сверх-бесконечности в 1, затем подставляете x = 2 - 1 / (1-t) и оцениваете в диапазоне 0 .. 1. Примечание. подстановка, я немного ржавый и здесь уже поздно.

1 голос
/ 05 декабря 2009

Результат численного интегрирования, когда одной из границ является бесконечность, также имеет хорошие шансы стать бесконечностью. И это займет бесконечное время;)

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

Если бы Apache Commons Math мог выполнять численное интегрирование для интегралов с бесконечными границами за конечное время, они бы его не раздавали бесплатно; -)

0 голосов
/ 05 декабря 2009

Может быть, это ваш алгоритм.

Если вы делаете что-то наивное, как правило Симпсона, это может занять очень много времени.

Если вы используете гауссовскую или логарифмическую квадратуру, возможно, вам повезет больше.

Какую функцию вы пытаетесь интегрировать, и какой алгоритм вы используете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...