Найти - Пользователи
Полная версия: lambdify функция с условием
Начало » Python для новичков » lambdify функция с условием
1
dd67
Некоторая функция w конструируется путем дифференцирования (как она выглядит не нужно знать, но пользоваться этой функцией нужно). Известно что при условии модуль (t-u) > epsilon функцией можно пользоваться, при модуль (t-u) > epsilon — нет. Как бы передать это условие в “конструктор” функции ? В примере ниже, результат правильный, но тратится время на бесполезное деление на ноль и вылетает предупреждение.
$ cat  ttest.py 
#!/usr/bin/python
import sympy
import numpy
x,y=sympy.symbols('x y')
f=1/(x-y)
v=sympy.diff(f,x)
w=sympy.lambdify((x,y),v)
t=numpy.array([1,2,3,4,5]).reshape(-1,1)
u=numpy.array([1,3]).reshape(1,-1)
plusIndex=numpy.abs(t-u)>0.00001
R=numpy.ones((5,2),dtype='d')
R[plusIndex]=w(t,u)[plusIndex]
print R


$ ./ttest.py
Warning: divide by zero encountered in true_divide
[[ 1. -0.25 ]
[-1. -1. ]
[-0.25 1. ]
[-0.11111111 -1. ]
[-0.0625 -0.25 ]]
fata1ex
Не очень понятна проблема. Почему нельзя использовать обычное ветвление с if?

Кажется, я понял вас, оберните в декоратор функцию. Если очень грубо:
>>> def bar(func):
...     def inner(a, b):
...         if b != 0:
...             return func(a,b)
...             
...     return inner
...     
>>> @bar
... def foo(a, b):
...     return a / b
...     
>>> foo(1, 2.0)
0.5
>>> foo(1, 0)
>>>
dd67
fata1ex
Кажется, я понял вас, оберните в декоратор функцию.

проблема в том, что мне нужно работать с массивом numpy.array. И в этом массиве игнорировать расчет некоторых элементов. И нужно как-то сказать lambdify функции: “не считать такие-то элементы”, т.е. сделать как-то так
w=sympy.lambdify((x,y), v if sympy.abs(x-y)>0.001 else 0.0 , modules='numpy')
но в этом коде, как я понимаю, проблема вот в чем : v - может быть числом, может быть вектором, а может быть матрицей.

А мне нужно указать, что не нужно считать какой-то конкретный элемент из всей матрицы, не прибегая к циклам.
dd67
fata1ex
Не очень понятна проблема.

Я не знаю как выглядит функция (сейчас в примере функция простая). Но я могу вычислить индексы выражения, в которых функцию нельзя считать (в проблемных местах будет использована другая функция). Сейчас не использую положительные индексы plusIndex:
$ cat ttest.py 
#!/usr/bin/python
import sympy
import numpy
x,y=sympy.symbols('x y')
f=1/(x-y)
v=sympy.diff(f,x)
sympy.pprint(v)
w=sympy.lambdify((x,y), v, modules='numpy')
t=numpy.array([1,2,3,4,5]).reshape(-1,1)
u=numpy.array([1,3]).reshape(1,-1)
plusIndex=numpy.abs(t-u)>0.00001
R=numpy.ones((5,2),dtype='d')
R=w(t,u)
print R


$ ./ttest.py
-1
────────
2
(x - y)
Warning: divide by zero encountered in true_divide
[[ -inf -0.25 ]
[-1. -1. ]
[-0.25 -inf]
[-0.11111111 -1. ]
[-0.0625 -0.25 ]]

в этом простом примере inf заменить не проблема, но в большой матрице не хочется на вычисление inf и nan тратить время + нехочется наблюдать Warning (а может и Error в более сложных случаях).
fata1ex
Почему вы не можете просто пробежаться по всем парам элементов (с помощью filter или генератора) и вызывать проблемную функцию только для подходящих пар. Делать это можно как в декораторе, так и явно.
dd67
fata1ex
Почему вы не можете просто пробежаться по всем парам элементов (с помощью filter или генератора) и вызывать проблемную функцию только для подходящих пар. Делать это можно как в декораторе, так и явно.

борюсь за скорость.
dd67
мне нужно решить задачу средствами нумпай, питоновские циклы сильно медленные.

используя http://docs.scipy.org/doc/numpy/reference/routines.html и пытаюсь что-то сделать, но с подходящими функциями возникают какие-то проблемы, например
RR=numpy.frompyfunc(w, plusIndex, plusIndex)
print RR

Traceback (most recent call last):
File "./ttest.py", line 17, in <module>
RR=numpy.frompyfunc(w, plusIndex, plusIndex)
TypeError: only length-1 arrays can be converted to Python scalars

функция w получат вектора строки и столбцы и должна возвратить матрицу
dd67
Получилось !

надеюсь по времени не сильно тормозит ….

def functW(_t_,_u_):
if _t_ != _u_: return w(_t_,_u_)
else: return 0.0
W=numpy.vectorize(functW)
print W(t,u)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB