From 079c558d4f9758cd2777a2808a02d64cb1f70c8e Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Tue, 9 Nov 2010 08:27:47 +0100 Subject: [PATCH] power::series(): handle someg (trivial) singularities of the exponent... ... so GiNaC can expand expressions like cos(x)^(sin(x)/x) // (x -> 0) (1 + x)^(1/x) // x -> 0 and so on. [Reported by Camille Gillot.] --- check/exam_pseries.cpp | 18 ++++++++++++++++++ ginac/pseries.cpp | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/check/exam_pseries.cpp b/check/exam_pseries.cpp index 42650cc0..a0f87ead 100644 --- a/check/exam_pseries.cpp +++ b/check/exam_pseries.cpp @@ -369,6 +369,23 @@ static unsigned exam_series13() return result; } +// Test if (1+x)^(1/x) can be expanded. +static unsigned exam_series14() +{ + unsigned result = 0; + + ex e = pow(1+x, sin(x)/x); + ex d = 1 + x - pow(x,3)/6 + Order(pow(x,4)); + try { + result += check_series(e,0,d,4); + } catch (const pole_error& err) { + clog << "series expansion of " << e << " at 0 raised an exception." << endl; + ++result; + } + + return result; +} + unsigned exam_pseries() { unsigned result = 0; @@ -388,6 +405,7 @@ unsigned exam_pseries() result += exam_series11(); cout << '.' << flush; result += exam_series12(); cout << '.' << flush; result += exam_series13(); cout << '.' << flush; + result += exam_series14(); cout << '.' << flush; return result; } diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 4a8d7d6a..c290fe0a 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -1116,6 +1116,29 @@ ex power::series(const relational & r, int order, unsigned options) const must_expand_basis = true; } + bool exponent_is_regular = true; + try { + exponent.subs(r, subs_options::no_pattern); + } catch (pole_error) { + exponent_is_regular = false; + } + + if (!exponent_is_regular) { + ex l = exponent*log(basis); + // this == exp(l); + ex le = l.series(r, order, options); + // Note: expanding exp(l) won't help, since that will attempt + // Taylor expansion, and fail (because exponent is "singular") + // Still l itself might be expanded in Taylor series. + // Examples: + // sin(x)/x*log(cos(x)) + // 1/x*log(1 + x) + return exp(le).series(r, order, options); + // Note: if l happens to have a Laurent expansion (with + // negative powers of (var - point)), expanding exp(le) + // will barf (which is The Right Thing). + } + // Is the expression of type something^(-int)? if (!must_expand_basis && !exponent.info(info_flags::negint) && (!is_a(basis) || !is_a(exponent))) -- 2.24.1