]> www.ginac.de Git - ginac.git/commitdiff
 author Alexei Sheplyakov Tue, 9 Nov 2010 07:27:47 +0000 (08:27 +0100) committer Richard Kreckel Tue, 9 Nov 2010 07:27:47 +0000 (08:27 +0100)
... 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 patch | blob | history ginac/pseries.cpp patch | blob | history

@@ -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;
}
@@ -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)