From f5f5525587a45db3ce0ef56c5bc76ac2bd4ca7af Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 30 Jan 2017 09:27:22 +0530 Subject: [PATCH 1/2] Use symengine in series --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 40 +++++++++++++----------- symengine/tests/test_series_expansion.py | 28 ++++++----------- symengine_version.txt | 2 +- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 392292202..81a253687 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -690,6 +690,7 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": bool has_symbol(const Basic &b, const Symbol &x) nogil except + + RCP[const Basic] coeff(const Basic &b, const Basic &x, const Basic &n) nogil except + set_basic free_symbols(const Basic &b) nogil except + cdef extern from "" namespace "std": diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index bc5b2aae7..126ab9e14 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -592,7 +592,15 @@ cdef class Basic(object): d[self] = 1 return d -def series(ex, x=None, x0=0, n=6, method='sympy', removeO=False): + def coeff(self, x, n=1): + cdef Symbol _x = sympify(x) + cdef Basic _n = sympify(n) + return c2py(symengine.coeff(deref(self.thisptr), deref(_x.thisptr), deref(_n.thisptr))) + + def has(self, *symbols): + return any([has_symbol(self, symbol) for symbol in symbols]) + +def series(ex, x=None, x0=0, n=6, as_deg_coef_pair=False): # TODO: check for x0 an infinity, see sympy/core/expr.py # TODO: nonzero x0 # underscored local vars are of symengine.py type @@ -609,35 +617,31 @@ def series(ex, x=None, x0=0, n=6, method='sympy', removeO=False): if not _x in syms: return _ex - if len(syms) > 1 or method == 'sympy': - from sympy import series as sy_series - return sy_series(_ex._sympy_(), _x._sympy_(), x0, n) - elif method == 'ring_series': - from sympy.polys.ring_series import rs_series - return rs_series(_ex._sympy_(), _x._sympy_(), n).as_expr().subs(x,x-x0) - elif method != 'symengine': - raise ValueError('unknown method in series()') + if x0 != 0: + _ex = _ex.subs({_x: _x + x0}) cdef RCP[const symengine.Symbol] X = symengine.rcp_static_cast_Symbol(_x.thisptr) - cdef unsigned int N = n cdef umap_int_basic umap cdef umap_int_basic_iterator iter, iterend - cdef Basic coef - umap = deref(symengine.series(_ex.thisptr, X, N)).as_dict() + if not as_deg_coef_pair: + b = c2py(deref(symengine.series(_ex.thisptr, X, n)).as_basic()) + if x0 != 0: + b = b.subs({_x: _x - x0}) + return b + + umap = deref(symengine.series(_ex.thisptr, X, n)).as_dict() - from sympy import Add as sAdd, Pow as sPow, O as sO iter = umap.begin() iterend = umap.end() poly = 0 l = [] while iter != iterend: - coef = c2py((deref(iter).second)) - l.append(sPow(_x,(deref(iter).first)) * coef) + l.append([deref(iter).first, c2py((deref(iter).second))]) inc(iter) - if removeO is False: - l.append(sO(sPow(_x, n))) - return sAdd(*l) + if as_deg_coef_pair: + return l + return add(*l) cdef class Symbol(Basic): diff --git a/symengine/tests/test_series_expansion.py b/symengine/tests/test_series_expansion.py index 609766ee5..3e6071f2e 100644 --- a/symengine/tests/test_series_expansion.py +++ b/symengine/tests/test_series_expansion.py @@ -1,30 +1,22 @@ from symengine.utilities import raises - -from sympy import Symbol, Integer, sin, cos, exp, sqrt, E -from symengine.lib.symengine_wrapper import series, have_piranha, have_flint, Symbol as SESymbol +from symengine.lib.symengine_wrapper import (series, have_piranha, have_flint, + Symbol, Integer, sin, cos, exp, sqrt, E) def test_series_expansion(): - if have_piranha: - x = SESymbol('x') - ex = series(sin(1+x), x, n=10, method='symengine') - assert ex.coeff(x,7) == -cos(1)/5040 - - if not have_flint and not have_piranha: - return + x = Symbol('x') + ex = series(sin(1+x), x, n=10) + assert ex.coeff(x,7) == -cos(1)/5040 x = Symbol('x') - ex = series(1/(1-x), x, n=10, method='symengine') - assert ex.coeff(x,9) == 1 - x = SESymbol('x') - ex = series(1/(1-x), x, n=10, method='symengine') + ex = series(1/(1-x), x, n=10) assert ex.coeff(x,9) == 1 - ex = series(sin(x)*cos(x), x, n=10, method='symengine') + ex = series(sin(x)*cos(x), x, n=10) assert ex.coeff(x,8) == 0 assert ex.coeff(x,9) == Integer(2)/Integer(2835) - ex = series(E**x, x, n=10, method='symengine') + ex = series(E**x, x, n=10) assert ex.coeff(x,9) == Integer(1)/Integer(362880) - ex1 = series(1/sqrt(4-x), x, n=50, method='symengine') - ex2 = series((4-x)**(Integer(-1)/Integer(2)), x, n=50, method='symengine') + ex1 = series(1/sqrt(4-x), x, n=50) + ex2 = series((4-x)**(Integer(-1)/Integer(2)), x, n=50) assert ex1.coeff(x,49) == ex2.coeff(x,49) diff --git a/symengine_version.txt b/symengine_version.txt index 0f6a694af..91212f2a6 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -d44e20c7437f6c6795a97354a213983abc77c9fe +0172e47349b7d158ee8a7186eb0a19a7f155a225 From 26b29864555ab4faf40cd165d7e80501fda1d2b1 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 30 Jan 2017 10:12:59 +0530 Subject: [PATCH 2/2] Fix .travis.yml install order so that git is not affected by sage libs --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9050ed591..955dcdf42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -94,19 +94,21 @@ install: - export TEST_CPP="no" - export MAKEFLAGS="-j2" - # Setup travis for Python wrappers - - source bin/install_travis.sh - - git clone https://github.com/symengine/symengine symengine-cpp - cd symengine-cpp - export SOURCE_DIR=`pwd` - git checkout `cat ../symengine_version.txt` + - cd .. + + # Setup travis for Python wrappers + - source bin/install_travis.sh # Setup travis for C++ library + - cd $SOURCE_DIR - if [[ "${WITH_SAGE}" != "yes" ]]; then source bin/install_travis.sh; fi # Build C++ library - - cd $PYTHON_SOURCE_DIR/symengine-cpp + - cd $SOURCE_DIR - bin/test_travis.sh - unset MAKEFLAGS