Форум сайта python.su
Имеется много символических функций (например, F и G в примере ниже), которые нельзя вычислять при x=y. Эти функции нужно преобразовать в numpy функции и векторизовать. Исключение случая x=y можно сделать одной функцией withoutZero.
Помогите одолеть синтаксис.
$ cat ttest.py #!/usr/bin/python import numpy import sympy x,y=sympy.symbols('x y') F=1/(x-y)**2 G=1/(x-y) def withoutZero(x,y,sFunct=0): if numpy.abs(x-y)>0.00001: return sympy.lambdify((x,y),sFunct,modules='numpy')(x,y) else: return 0.0 KF=numpy.vectorize(withoutZero(x,y,F)) KG=numpy.vectorize(withoutZero(x,y,G)) print KF(1,2) $ ./ttest.py Traceback (most recent call last): File "./ttest.py", line 13, in <module> print KF(1,2) File "/usr/lib/pymodules/python2.7/numpy/lib/function_base.py", line 1813, in __call__ theout = self.thefunc(*newargs) TypeError: __call__() takes exactly 2 arguments (3 given)
Офлайн
Думаю, как то так
# -*- coding:utf-8 -*- import numpy import sympy x,y=sympy.symbols('x y') F=1/(x-y)**2 G=1/(x-y) def withoutZero(sFunct=None): def lmbd(i,j): if numpy.abs(i-j)>0.00001: return sympy.lambdify((x,y),sFunct,modules='numpy')(i,j) else: return 0.0 return lmbd KF=numpy.vectorize(withoutZero(sFunct=F)) KG=numpy.vectorize(withoutZero(sFunct=G)) print KF([1,2,4,5,6, 7],[2,4,5,6,4,3]) print KG([1,2,4,5,6, 7],[2,4,5,6,4,3])
Офлайн
Можно ли как-то оптимизировать функцию withoutZero, таким образом, чтобы она быстрее работала c numpy-массивами?
Эту функцию требуется вызывать для больших numpy-массивов, например:
x,y=sympy.symbols('x y') G=1/(x-y)+sympy.log(sympy.abs(x-y)) F=sympy.diff(G,x) sympy.pprint(F) def withoutZero(sFunct=None,eps=0.0001): def lmbd(a,b): if numpy.abs(a-b)>eps: return sympy.lambdify((x,y),sFunct,modules='numpy')(a,b) else: return 0.0 return numpy.vectorize(lmbd) KF=withoutZero(sFunct=F) n=1000 t=numpy.ones(n) u=2.*numpy.ones(n) print KF(t,u)
Отредактировано dd67 (Июнь 22, 2012 23:23:27)
Офлайн
код без векторизаии поэлементной функции работает гораздо быстрее (т.к. vectorize, даже с otypes= работает очень медленно). Можно ли в коде ниже избавиться от расчетов элементов с делением на ноль, если их индексы известны (на месте таких элеметов д.б. ноль)?
#!/usr/bin/python import numpy import sympy x,y=sympy.symbols('x y') G=1/(x-y)+sympy.log(sympy.abs(x-y)) F=sympy.diff(G,x) sympy.pprint(F) def lmbdFun(sFunct=None): return sympy.lambdify((x,y),sFunct,modules='numpy') KF=lmbdFun(sFunct=F) t=numpy.array([1,2,3,4,5]) u=numpy.array([1,3,3,5,5]) res=numpy.zeros(5) good=(t!=u) res[good]=KF(t,u)[good] print res
$ ./ttest.py
re(x - y) 1
───────── - ────────
2 2
│x - y│ (x - y)
Warning: invalid value encountered in true_divide
Warning: divide by zero encountered in true_divide
[ 0. -2. 0. -2. 0.]
$ cat ./ttest.py #!/usr/bin/python import numpy import sympy x,y=sympy.symbols('x y') G=1/(x-y)+sympy.log(sympy.abs(x-y)) F=sympy.diff(G,x) sympy.pprint(F) def lmbdFun(sFunct=None): return sympy.lambdify((x,y),sFunct,modules='numpy') KF=lmbdFun(sFunct=F) t=numpy.array([1,2,3,4,5]) u=numpy.array([1,3,3,5,5]) res=numpy.zeros(5) good=(t!=u) bad=(t==u) t[bad]=u[bad]+1 res[good]=KF(t,u)[good] print res
Отредактировано dd67 (Июнь 24, 2012 16:13:54)
Офлайн