Гамма-функция и факториал: вычислительные вопросы

Тема в разделе "Кухня", создана пользователем Pia, 19 окт 2008.

  1. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Можно ли найти формулу и написать программу точнее, чем эта?
    Программа определяет факториалы чисел от -1754.5 до 10^4928. Точность - до 18 знаков, включая степень числа.
    —————————————
    {$N+}

    var
    n:extended;
    d:array[0..101]of extended;

    function power(a:extended;f:longint):extended;
    var
    g:longint;
    h:extended;
    begin
    if f = 0 then power:=1 else
    begin
    h:=a;
    for g:=2 to f do h:=h*a;
    power:=h;
    end;
    end;

    function lnfact(z:extended):extended;
    var
    r,i,old:extended;
    j:byte;
    begin
    i:=0;
    old:=0;
    for j := 0 to 50 do if (ln(z)*j)>11352 then break else
    begin
    i:=i+d[j]/power(z,j);
    if old = i then break else old:=i;
    end;
    r:=ln(z/exp(1))*z+ln(sqrt(2*z*pi))+ln(i);
    lnfact:=r;
    end;

    function smallfact(x:extended):extended;
    var
    r,z:extended;
    a,b:byte;
    begin
    a:=trunc(x);
    z:=frac(x);
    r:=exp(lnfact(7+z));
    for b:=7 downto a+1 do r:=r/(b+z);
    smallfact:=r;
    end;

    function negfact(x:extended):extended;
    var
    z:extended;
    begin
    if (-x) < 7 then z:=smallfact(-x) else z:=exp(lnfact(-x));
    negfact:=pi/sin(n*pi)*n/z;
    end;

    function double(f:longint):extended;
    var
    k:longint;
    r:extended;
    begin
    r:=1;
    for k:=1 to (f-1) div 2 do r:=r*(k*2+1);
    double:=r;
    end;

    procedure filldata;
    var
    t,k:byte;
    s:extended;
    begin
    d[0]:=1;
    d[1]:=1;
    for t:=2 to 101 do
    begin
    s:=0;
    for k:=2 to t-1 do s:=s+(k*d[k]*d[t+1-k]);
    d[t]:=(d[t-1]-s)/(t+1);
    end;
    for t:=1 to 50 do d[t]:=double(2*t+1)*d[t*2+1];
    end;

    procedure bigfact;
    var
    r1,r2:extended;
    begin
    r1:=lnfact(n)/ln(10);
    r2:=exp(frac(r1)*ln(10));
    r1:=int(r1);
    writeln('n! = ',r2:1:17,'E+',r1:0:0);
    end;

    function fact(x:extended):extended;
    begin
    if n < 0
    then fact:=negfact(x)
    else if n < 7
    then fact:=smallfact(x)
    else fact:=exp(lnfact(x));
    end;

    begin
    filldata;
    writeln('n!, Ctrl-C - exit');
    repeat
    write('n = ');
    readln(n);
    if (n < -1754.5) or (n > 1E+4928)
    then writeln('Sorry for n exceeds the limits of -1754.5 to 10^4928.')
    else if (n < 0) and (frac(n) = 0)
    then writeln('Sorry for n is negative integer; division by zero.')
    else if n <= 1754.5
    then writeln('n! =',fact(n):26)
    else bigfact;
    until false;
    end.
    —————————————
  2. Муркенштейн Гастролёр

    • Участник
    Рег.:
    20.02.2006
    Сообщения:
    1.794
    Симпатии:
    15
    Репутация:
    2
    Адрес:
    Nowhere
    Оффлайн
    Обычному виндозному калькулятору это ограничение нипочём.
  3. Yurie Учаcтник

    • Участник
    Рег.:
    04.11.2006
    Сообщения:
    601
    Симпатии:
    1
    Репутация:
    0
    Оффлайн
  4. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Да, калькулятор классно это делает. Но ограничения всё же есть. Калькулятор не может решить, например 4 000 000 000!, а найти логарифм его несравнимо проще.
  5. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    По первой же ссылке нашёл аглотитм только для целых n (integer для Delphi). Разве можно найти ещё что-то?
  6. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
  7. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
  8. krey Михаил Кройтор

    • Команда форума
    Рег.:
    10.04.2006
    Сообщения:
    3.709
    Симпатии:
    50
    Репутация:
    1
    Адрес:
    Кишинев
    Оффлайн
    я в школе на старых машинах (Агат) вычислял 5000!
  9. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Вот версия программы, для которой практически нет ограничений на величину n.
    Правда, точность ниже, чем у предыдущей. Я думаю использовать другую формулу.
    Калькулятор Windows врядли подсчитает вам хотябы (9!)! А этот - сразу решает даже (20!)! (Число настолько большое, что подсчитать даже количесво знаков получается лишь приблизительно).
    Например, попробуйте проверить на Калькуляторе Windows моё утверждение, что (15!)!=6*10^15276520209205.
    —————————————————————-
    Ввёл изменения в первый пост.
    —————————————————-
  10. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
    Да тут и без калькулятора видно, что они не равны. :)
  11. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
    При чём тут ln(n!)? Там по ссылкам разные ряды для гамма-функции, позволяющие с произвольной точностью посчитать n!.

  12. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    А сейчас это делается on-line.
    Вот ссылка (я сейчас не могу открыть), где есть ссылка на калькулятор:
    http://ru.wikipedia.org/wiki/Факториал
    Он вычисляет только положительные целые до 5000. Но зато абсолютно точно.
  13. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Что значит "не равны"? С заявленной точностью, равны.
  14. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Читаем дальше:
    То есть, при 18 знаках мы найдём только 11. И это при том, что я не знаю, как перевести Г(n) в n! при нецелом n.
  15. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
    Ну вы тут точность с которой считали не писали, да и знак "равно" стоит :D

    Spouge's approximation c любой точностью приближает, так что ответ на ваш пост #1 — да, можно.
  16. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
    А что это за зверь такой, n! для нецелых?
  17. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    У меня другого знака нет. Точность до последнего заявленного знака.

    Вот моя программа как раз вычисляет для целых и нецелых.
  18. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
    Интересное определение.
  19. Хайдук Учаcтник

    • Участник
    Рег.:
    03.12.2007
    Сообщения:
    4.489
    Симпатии:
    9
    Репутация:
    0
    Оффлайн
    А Гамма функция не определена везде на реальной оси или как? Значит должна быть какая-то конвенция для нецелых n :rolleyes:
  20. drowsy Учаcтник

    • Участник
    Рег.:
    08.09.2006
    Сообщения:
    1.282
    Симпатии:
    1
    Репутация:
    0
    Адрес:
    Toronto, Canada
    Оффлайн
    В том-то и дело, что Гамма-функция определена много где, а вот про факториал впервые слышу.
  21. NS Нефёдов Сергей

    • Заслуженный
    • Ветеран
    • Старожил
    Рег.:
    02.05.2006
    Сообщения:
    6.811
    Симпатии:
    96
    Репутация:
    3
    Адрес:
    Санкт-Петербург
    Оффлайн
    Ну, по-определению факториал только для целых... Но! В комбинаторике не принято использовать гамма-функцию, а если я считаю сочетания по нецелым значениям? То мне нужен дробный факториал! Примеры когда нужно обощить сочетания на нецелые значения приводить не буду, но они есть...
  22. Vladimirovich Консультант

    • Ветеран
    • Заблокирован
    • Старожил
    Рег.:
    27.09.2006
    Сообщения:
    6.007
    Симпатии:
    810
    Репутация:
    31
    Нарушения:
    31
    Адрес:
    https://quantoforum.ru/
    Оффлайн
    Адназначна :)
    Сам факт хардкода коэффициентов ряда в вычислительной программе .........
  23. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    9.491
    Симпатии:
    3.118
    Репутация:
    95
    Адрес:
    Москва
    Оффлайн
    Можно скачать интерпретатор Схемы, Хаскеля или какого-нибудь ещё подобного языка - там такие штуки на раз делаются...
  24. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Vladimirovich, drowsy.
    Ну так я знаю, что можно. Факт тот, что кроме меня это никто не напишет.
  25. Vladimirovich Консультант

    • Ветеран
    • Заблокирован
    • Старожил
    Рег.:
    27.09.2006
    Сообщения:
    6.007
    Симпатии:
    810
    Репутация:
    31
    Нарушения:
    31
    Адрес:
    https://quantoforum.ru/
    Оффлайн
    :lol:
    Pia, знаете старинный анекдот про неуловимого Джо?
    Он неуловим, потому что его никто не ловит, потому что он никому не нужен :)
    Вот поэтому никто и не напишет :)
    P.S. Все уже давно написано, причем с любой требуемой точностью.
  26. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Да, но у нас-то этого "всего" нет. Кроме Калькулятора Windows, но он ограничен. Нужно попросить Юрия Осипова, чтобы дизассемблировавал.
  27. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    9.491
    Симпатии:
    3.118
    Репутация:
    95
    Адрес:
    Москва
    Оффлайн
    Если что-то не включено в дистрибутив Windows, это не значит, что его нет.
    Всё есть, и даже даром: http://gmplib.org/
  28. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Это даже лучше, чем предыдущий калькулятор по ссылке Wiki. Но опять же, считатает только целые.
    Возможно, я буду использовать её библиотеку для своей программы. Но нужна более точная формула. Например, как Калькулятор Windows так точно показывает, что 0.5! = sqrt(pi)/2.
  29. Vladimirovich Консультант

    • Ветеран
    • Заблокирован
    • Старожил
    Рег.:
    27.09.2006
    Сообщения:
    6.007
    Симпатии:
    810
    Репутация:
    31
    Нарушения:
    31
    Адрес:
    https://quantoforum.ru/
    Оффлайн
    Pia, запустите поиск по гуглу - гамма-функция алгоритм
  30. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    9.491
    Симпатии:
    3.118
    Репутация:
    95
    Адрес:
    Москва
    Оффлайн
    "GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers."
  31. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Последнее не относится к факториалам, для чего нужна другая формула нежели простое умножение, которую нужно взять где-то ещё.
    При чём тут гамма-функция? Если даже если она точнее, чем та формула, что у меня уже есть, то как перевести?
  32. Vladimirovich Консультант

    • Ветеран
    • Заблокирован
    • Старожил
    Рег.:
    27.09.2006
    Сообщения:
    6.007
    Симпатии:
    810
    Репутация:
    31
    Нарушения:
    31
    Адрес:
    https://quantoforum.ru/
    Оффлайн
    Pia, прежде чем что либо считать, неплохо узнать что именно :)

    Гамма-функция и есть обобщение факториала для вещественных и комплексных чисел
    Популярненько здесь
    http://ru.wikipedia.org/wiki/Гамма-функция

    для всех натуральных чисел n Г(n+1) = n!
    Вам нужен алгоритм расчета Гамма-функции для нецелых.
  33. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Вот именно, что натуральное число считается целым числом, во всяком случае здесь.
    И почему Вы решили, что алгоритм расчёта Гамма-функции точнее, чем тот алгоритм расчёта факториалов, что у меня уже есть?
  34. Vladimirovich Консультант

    • Ветеран
    • Заблокирован
    • Старожил
    Рег.:
    27.09.2006
    Сообщения:
    6.007
    Симпатии:
    810
    Репутация:
    31
    Нарушения:
    31
    Адрес:
    https://quantoforum.ru/
    Оффлайн
    Григория на Вас нет :)

    Вы что считаете - факториалы для нецелых? Ну так это и есть Гамма-функция.
    Название такое. С 18 века существует.
    Нет такого понятия факториала для нецелых.

    Я не мог сказать, что алгоритм расчёта Гамма-функции точнее чем факториалов :)
    Поскольку это ОДНО И ТО ЖЕ.
    Я сказал, что есть более точные алгоритмы, чем Ваш, и сказал что искать.
    P.S Разумеется никто не гарантирует, что в интернетовской помойке Вы не найдете менее точный. :)
  35. TopicStarter Overlay

    Pia Учаcтник

    • Участник
    Рег.:
    11.06.2007
    Сообщения:
    537
    Симпатии:
    0
    Репутация:
    0
    Оффлайн
    Ну так ясно, что искать, вот я и ищу.
    Если бы гамма-функция и факториал были бы "одно и то же", это можно было доказать.
    Г(0.5)=0.886
    -0.5!=1.77
    Г(-0.5+1)=Г(0.5)<>-0.5!

Поделиться этой страницей