2017-05-24 2 views
-2

J'utilise la fonction spéciale lambertw (k=-1) en Python 3 et je dois l'utiliser avec des nombres supérieurs/inférieurs au nombre float maximum/minimum (1.7976931348623157e+308) .Utiliser un nombre plus élevé que le flottant maximum pour la fonction spéciale lambertw

Que puis-je faire?

Aussi j'ai essayé avec "décimal", mais cela n'a pas fonctionné, je. e.,

from decimal import Decimal 
from scipy.special import lambertw 

lambertw(Decimal('3.1E+600')) 

obtenu ce,

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
File "/share/apps/sistema/Python-3.5.1/lib/python3.5/site-packages/scipy/special/lambertw.py", line 107, in lambertw 
return _lambertw(z, k, tol) 
TypeError: ufunc '_lambertw' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''  
+1

la première chose que vous pouvez faire est de poster ce que vous avez essayé avec une explication des raisons pour lesquelles il n'a pas wo rk; dire aux gens ici que * "j'ai essayé avec" décimal ", mais ça n'a pas marché". * n'est pas utile. –

+1

Je serais surpris si 'scipy.special.lambertw' fonctionne avec' decimal.Decimal' ... –

Répondre

1

La bibliothèque mpmath dans SymPy comprend une mise en œuvre de lambertw. mpmath implémente l'arithmétique à virgule flottante de précision arbitraire.

Voici un exemple. Tout d'abord, importer mpmath de sympy et définissez les chiffres de précision à 100 (choisi arbitrairement - le changement pour répondre à vos besoins):

In [96]: from sympy import mpmath 

In [97]: mpmath.mp.dps = 100 

Vérifiez que la fonction mpmath donne les mêmes résultats que scipy.special.lambertw:

In [98]: from scipy.special import lambertw 

In [99]: lambertw(123.45) 
Out[99]: (3.5491328966138256+0j) 

In [100]: mpmath.lambertw(123.45) 
Out[100]: mpf('3.549132896613825444243187580460572741065183903716765715536934583554830913412258511917029758623080475405') 

Calculer lambertw(3.1e600). L'argument est entré comme une chaîne, car nous ne pouvons pas représenter 3.1e600 comme une valeur à virgule flottante normale. mpmath convertira la chaîne en une valeur à virgule flottante de haute précision en utilisant la précision que nous avons définie précédemment.

In [101]: mpmath.lambertw('3.1e600') 
Out[101]: mpf('1375.455917376503282959382815269413629072666427317318260231463057587794635136887591876065911283365916388') 

Nous pouvons également créer une x variable pour maintenir la valeur d'entrée, puis appelez mpmath.lambertw(x):

In [102]: x = mpmath.mpf('3.1e600') 

In [103]: x 
Out[103]: mpf('3.099999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999e+600') 

In [104]: mpmath.lambertw(x) 
Out[104]: mpf('1375.455917376503282959382815269413629072666427317318260231463057587794635136887591876065911283365916388') 

Le résultat peut être représenté comme une valeur en virgule flottante régulière, nous passons donc à la fonction builtin float() pour effectuer la conversion:

In [105]: float(mpmath.lambertw(x)) 
Out[105]: 1375.455917376503 
+0

Merci! Ça marche. – iaraya

2

Le module decimal devrait être en mesure de résoudre votre problème. Le problème que vous avez rencontré est peut-être que vous n'avez pas défini la précision supérieure à la valeur par défaut 28, as mentioned in the docs. Pour ce faire, appelez simplement getcontext().prec = 100 ou quel que soit le degré de précision dont vous avez besoin.

Par exemple, en utilisant votre numéro d'exemple, je viens de rencontrer cette session interactive:

>>> decimal.getcontext().prec = 1000 
>>> d = decimal.Decimal(1.7976931348623157e+308) 
>>> d 
Decimal('179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368') 
+0

Mon problème est d'utiliser ce numéro dans la fonction lambert ... – iaraya

+0

Ah, merci pour votre modification à la question, il était assez vague au début. J'ai fait un peu de recherche et on dirait que vous ne pouvez pas; scipy semble ne prendre en charge que les types numériques natifs: https://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html – Personman