ValueError: math domain error во время вычисления математического выражения

458 просмотра
0
0 Комментариев

Есть простая функция:

import math
import numpy as np
 
 
def func(x):
   k = (0.48 ** 3 + math.sin(1.2 * x) / (math.acos(x * 0.48 * x) + math.exp(-x / 2)))
return k

При итерации по простому массиву все работает:

zad2 = [0.25, 0.36, 0.56, 0.94, 1.28]
for n in zad2:
       print(func(n))

однако, при итерации по объекту numpy.arange возникает исключение ValueError: math domain error:

arr = np.arange(0.7, 2.2, 0.3)
 
print("zad1")
for s in arr:
    print(func(s))

Трассировка полностью:

 0.2325420603873083
 Traceback (most recent call last):
 0.2892269610836477
 0.3967601267945787
 File "C:/Users/Pipekalo/Google Диск/обучение 2 курс/py/algo_9.py", line 16, in <module>
 0.6246192801373474
 print(func(s))
 0.9482530298513533
 File "C:/Users/Pipekalo/Google Диск/обучение 2 курс/py/algo_9.py", line 6, in func
 zad1
 k = (0.48 ** 3 + math.sin(1.2 * x) / (math.acos(x * 0.48 * x) +   math.exp(-x / 2)))
 0.4759605810894156
 ValueError: math domain error
 0.6664782637398168
 0.9826538650316734

Первые 5 выводов из списка, а дальше 3 из массива и ошибка вот какая то странная. IDE — PyCharm, версия питона 3.6.


Добавить комментарий

1 Ответы

Python Опубликовано 14.12.2018
0

Вы вышли за область определения для арккосинуса [-pi/2, pi/2]:

In [83]: arr = np.arange(0.7, 2.2, 0.3)
 
In [84]: arr
Out[84]: array([ 0.7,  1. ,  1.3,  1.6,  1.9,  2.2])
 
In [85]: x = 1.9
 
In [86]: math.acos(x * 0.48 * x)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-86-116284452697> in <module>()
----> 1 math.acos(x * 0.48 * x)
 
ValueError: math domain error

проверка:

In [90]: x * 0.48 * x
Out[90]: 1.7327999999999997
 
In [91]: x * 0.48 * x <= math.pi/2
Out[91]: False

А вообще, раз вы уже используете NumPy, я бы вам советовал пользоваться «векторизированными» функциями, вместо циклов:

In [99]: def func_vect(x):
    ...:     if not isinstance(x, (np.ndarray, np.generic)):
    ...:         a = np.array(x)
    ...:     else:
    ...:         a = x
    ...:     return (0.48 ** 3 + np.sin(1.2 * a) / (np.arccos(a * 0.48 * a) + np.exp(-a / 2)))
    ...:
 
In [100]: func_vect(arr)
C:\Anaconda3\Scripts\ipython-script.py:6: RuntimeWarning: invalid value encountered in arccos
Out[100]: array([ 0.47596058,  0.66647826,  0.98265387,         nan,         nan,         nan])
 
In [101]: func_vect(zad2)
Out[101]: array([ 0.23254206,  0.28922696,  0.39676013,  0.62461928,  0.94825303])

nan — обозначает Not a Number

Сравнение производительности для массива из 1.000 элементов:

In [107]: arr = np.random.rand(10**3)
 
In [108]: l = arr.tolist()
 
In [109]: len(arr)
Out[109]: 1000
 
In [110]: len(l)
Out[110]: 1000
 
In [111]: %%timeit
     ...: for n in l:
     ...:     func(n)
     ...:
1000 loops, best of 3: 933 µs per loop
 
In [112]: %timeit func_vect(arr)
10000 loops, best of 3: 54 µs per loop

а теперь для массива из 1.000.000 элементов:

In [113]: arr = np.random.rand(10**6)
 
In [114]: l = arr.tolist()
 
In [115]: len(arr)
Out[115]: 1000000
 
In [116]: len(l)
Out[116]: 1000000
 
In [117]: %%timeit
     ...: for n in l:
     ...:     func(n)
     ...:
1 loop, best of 3: 949 ms per loop
 
In [118]: %timeit func_vect(arr)
10 loops, best of 3: 59.4 ms per loop

Добавить комментарий
Напишите свой ответ на данный вопрос.
Scroll Up