6
votes

Problème d'arithmétique à l'aide de logarithmes pour éviter le débit numérique (prendre 2)

J'ai deux listes de fractions;

dire a = [1/212, 5/212, 3/212, ...]

et b = [4/143, 7/143, 2/143, ...] .

Si nous définissons a '= a [0] * a [1] * A [2] * ... et B' = B [0] * b [1] * b [2] * ...

Je veux calculer une valeur normalisée d'un 'et de B'

c'est-à-dire spécifiquement les valeurs de a '/ (a' + b ') et b' / (a ​​'+ b')

Mes problèmes sont A SONT B sont à la fois assez longs et chaque valeur est petite de sorte que le calcul du produit provoque un débordement numérique très rapidement ...

Je crois comprendre tourner le produit en une somme via des logarithmes peut m'aider à déterminer lequel d'un 'ou B' est plus grand

IE max (journal (A [0]) + journal (A [1]) + ..., journal (b [0]) + journal (B [1]) + ...) < / code>

Et que, à l'aide de journaux, je peux calculer la valeur de A '/ B' mais comment puis-je faire a '/ a' + b '

Mon meilleur pari à ce jour consiste à conserver les représentations numériques en tant que fractions, à savoir a = [[1 2112], [5 2112], [3,212], ...] et mettre en œuvre mon propre arithmétique mais Il devient maladroit et j'ai le sentiment qu'il y a une manière (simple) de logarithmes, je manque tout simplement ...

Les numérateurs pour A et B ne proviennent pas d'une séquence. Ils pourraient aussi bien être aléatoire dans le but de cette question. Si cela aide les dénominateurs à toutes les valeurs d'A sont les mêmes, tout comme tous les dénominateurs de b.

Des idées les plus bienvenues!

(ps. j'ai demandé à un Question similaire Il y a 24 heures concernant le rapport a '/ b' mais c'était en fait la question mauvaise question à poser. Je suis en fait après a '/ (a' + B ') . Désolé, mon erreur.)


2 commentaires

Désolé, cela signifie-t-il un '/ (A' + B ') et B' / (A '+ B')? Vous manquez des parenthèses?


Oui, merci, je l'ai corrigé.


4 Réponses :


5
votes

Je vois peu de façons ici

​​Tout d'abord, vous pouvez remarquer que P> xxx pré>

et vous savez comment calculer B '/ A' code " > Avec des logarithmes. P>

Un autre moyen est de mettre en œuvre votre propre arithmétique rationnel, mais vous n'avez pas besoin d'aller loin à ce sujet. Puisque vous savez que les dénominateurs sont les mêmes pour l'ensemble de l'ensemble, il vous donne immédiatement P>

numerator(A') = numerator(a[0]) * numerator(a[1]) ...
denumerator(A') = denumerator(a[0]) ^ A.length


5 commentaires

Python 3.x a un Bigint intégré. Un Int est un Bigint. Cela aide à garder la précision élevée.


@Hamish, il pourrait réellement utiliser double pour les énumérateurs. Il a des problèmes de délaiement et je ne pense pas qu'il souhaite avoir des calculs super précis, juste assez précis.


Eh bien ... lorsque vous divisez un petit nombre par un autre, vous voudrez peut-être garder une bonne précision pour les deux.


Quelque chose comme a '/ (a' + b ') = 1 / (1 + b' / a ') est ce que je cherchais, merci! Cela fait partie d'une plus grande pièce, donc je tiens à garder dans le plus grand nombre possible de logarithmes pour économiser une plus grande réécriture. à votre santé!


(En plus, je l'écris dans Ruby, c'est un prototype pour le cochon Hadoop, donc j'essaye d'ignorer le plus rationnel autant que possible)



1
votes

Mon meilleur pari à ce jour est de conserver les représentations numériques comme des fractions et de mettre en œuvre mon propre arithmétique, mais il devient maladroit

Quelle langue utilisez-vous? Si vous pouvez surcharger des opérateurs, il devrait être vraiment facile de créer une classe que vous pouvez traiter comme un nombre à peu près partout.

Par exemple, déterminer si une fraction a / b est plus grande que c / d est essentiellement comparable à ce que a * d est plus grand que b * c .


0 commentaires

1
votes

A et B ont le même dénominateur dans chaque fraction que vous mentionnez. Est-ce vrai pour chaque terme de la liste? Si tel est le cas, pourquoi ne vous rendez-vous pas en compte lorsque vous calculez le produit? Le dénominateur sera simplement x ^ n, lorsque X est la valeur et n est le nombre de termes de la liste.

Si vous faites cela, vous aurez le problème opposé: débordement dans le numérateur. Vous savez qu'il ne peut pas être plus petit que max (x) ^ n, où max (x) est la valeur maximale du numérateur et n est le nombre de termes de la liste. Si vous pouvez calculer cela, vous pouvez voir si votre ordinateur aura un problème. Vous ne pouvez pas mettre 10 livres de quelque chose dans un sac de 5 livres.

Malheureusement, les propriétés des logarithmes vous limitent aux simplifications suivantes:

 text alt
(source: equationsheet.com )

et

 text alt
(source: EquationsHeet.com )

Donc, vous êtes coincé avec:

 text alt
(source: equationsheet.com )

Si vous utilisez une langue prenant en charge des numéros de précision infinis (par exemple, Java BigDecimal), cela pourrait rendre votre vie un peu plus facile. Mais il y a encore un bon argument pour avoir fait de penser avant de calculer. Pourquoi utiliser une force brute quand vous pouvez être élégant?


0 commentaires

0
votes

Eh bien ... si vous savez a '(a' + b ') , alors b' (A '+ b') doit être un moins celui qui. Personnellement, je n'utiliserais pas de logarithmes. J'utiliserais les fractions réelles. J'utiliserais également une sorte de classe de Bigint pour représenter le numérateur et le dénominateur. Quelle langue utilisez-vous? Python peut être un bon ajustement.


0 commentaires