Форум сайта python.su
1
Некоторая функция 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 ]]
Отредактировано dd67 (Май 14, 2012 17:57:55)
Офлайн
52
Не очень понятна проблема. Почему нельзя использовать обычное ветвление с 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) >>>
Отредактировано fata1ex (Май 14, 2012 18:43:20)
Офлайн
1
fata1ex
Кажется, я понял вас, оберните в декоратор функцию.
w=sympy.lambdify((x,y), v if sympy.abs(x-y)>0.001 else 0.0 , modules='numpy')
Офлайн
1
fata1ex
Не очень понятна проблема.
$ 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 ]]
Отредактировано dd67 (Май 14, 2012 19:08:26)
Офлайн
52
Почему вы не можете просто пробежаться по всем парам элементов (с помощью filter или генератора) и вызывать проблемную функцию только для подходящих пар. Делать это можно как в декораторе, так и явно.
Офлайн
1
fata1ex
Почему вы не можете просто пробежаться по всем парам элементов (с помощью filter или генератора) и вызывать проблемную функцию только для подходящих пар. Делать это можно как в декораторе, так и явно.
Офлайн
1
мне нужно решить задачу средствами нумпай, питоновские циклы сильно медленные.
используя 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
Отредактировано dd67 (Май 14, 2012 19:40:59)
Офлайн
1
Получилось !
надеюсь по времени не сильно тормозит ….
def functW(_t_,_u_):
if _t_ != _u_: return w(_t_,_u_)
else: return 0.0
W=numpy.vectorize(functW)
print W(t,u)
Офлайн