проблема с арифметикой с использованием логартмов, чтобы избежать числового занижения - PullRequest
4 голосов
/ 18 февраля 2010

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

скажем 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' больше

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

но мне нужно фактическое соотношение ....

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

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

Любые идеи приветствуются!

Мат

Ответы [ 3 ]

4 голосов
/ 18 февраля 2010

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

A' / B' = a[0] / b[0] * a[1] / b[1] * a[2] / b[2] * ...
1 голос
/ 18 февраля 2010

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

0 голосов
/ 18 февраля 2010

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

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

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

Возможно, у меня есть некоторые дроби вверх ногами, но я думаю, вы можете это выяснить?

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