проблема с арифметикой с использованием логарифмов, чтобы избежать числового недополнения

У меня есть два списка фракций;

скажи A = [ 1/212, 5/212, 3/212, ... ]

и B = [ 4/143, 7/143, 2/143, ... ].

Если мы определим A' = a[0] * a[1] * a[2] * ... и B' = b[0] * b[1] * b[2] * ...

Я хочу рассчитать значения A' / B',

Моя проблема в том, что A и B оба довольно длинные, и каждое значение маленькое, поэтому вычисление продукта очень быстро приводит к численному недостатку...

Я понимаю, что преобразование произведения в сумму с помощью логарифмов может помочь мне определить, какой из A' или B' больше

ie max( log(a[0])+log(a[1])+..., log(b[0])+log(b[1])+... )

но мне нужно реальное соотношение....

Мой лучший выбор на сегодняшний день - сохранить представление чисел в виде дробей, то есть A = [ [1,212], [5,212], [3,212], ... ], и реализовать мою собственную арифметику, но она становится неуклюжей, и у меня есть ощущение, что есть (простой) способ логарифмов, который я просто отсутствует....

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

Приветствуются любые идеи!

Мат


person mat kelcey    schedule 18.02.2010    source источник


Ответы (3)


Вы можете вычислить его немного в другом порядке:

A' / B' = a[0] / b[0] * a[1] / b[1] * a[2] / b[2] * ...
person Mark Byers    schedule 18.02.2010
comment
Потрясающие! это должно работать нормально. Я не мог видеть леса за деревьями. - person mat kelcey; 18.02.2010
comment
Хороший ответ. Ты подтолкнул меня на это :) - person OJ.; 18.02.2010

Если вы хотите сохранить его в логарифмах, помните, что A/B соответствует журналу A - журналу B, поэтому после суммирования логарифмов A и B вы можете найти отношение большего к меньшему, возведя в степень ваш журнал база с max(logsumA, logsumB)-min(logsumA,logsumB).

person Vatine    schedule 18.02.2010
comment
спасибо за это. по другим причинам (поскольку это часть более широкой картины) я мотивирован вести журналы. ваше здоровье! - person mat kelcey; 18.02.2010

Вычеркните числители и знаменатели, так как они одинаковы для всей последовательности. Вычислите отношение числителей поэлементно (скорее, как предлагает @Mark), наконец, умножьте результат на правую степень знаменателя B/знаменателя A.

Или, если это угрожает целочисленному переполнению при вычислении произведения числителей или степеней знаменателей, что-то вроде:

A'/B' = (numerator(A[0])/numerator(b[0]))*(denominator(B)/denominator(A) * ...

Я, вероятно, перевернул некоторые дроби, но я думаю, вы можете понять это?

person High Performance Mark    schedule 18.02.2010