[GiNaC-list] Fwd: Performance problem with series

Frieder Kalisch kalisch at tphys.uni-heidelberg.de
Thu Jan 20 12:42:04 CET 2005

```Hi Chris,

Am Mittwoch 19 Januar 2005 18:31 schrieb Chris Dams:
> Ad (1): I think series expansion should most of the time not be done by
> repeated differentiation. What if some large addition appears as a
> subexpression? The chain rule together with expansion of the derivatives
> (in the sense of .expand()) will cause expression explosion and happyness
> is not going to occur.

I admit that series expansion by repeated differentiation is not always the
right solution. However, given the patch at the end of this mail, which cures
the unexpandedness of power_const, series is still slower by a factor of 10
than series expansion by differentiation. Maybe there just isn't one single best
method for series expansion... Therefore I think that ginac should provide a
way to compute series by differientiation. I suggest adding a method to ex,
which is essentially a call to basic::series.

Given Your reasoning, I don't understand the implementation of power::series
anymore. E.g. pow(sin(something very complicated without singularity), 5) is
expanded by repeated differentiation. basic::series is called in the if
statement just below  "// Is the expression of type something^(-int)?".

> Ad (2): I think that the expansion coefficients should be in expandend
> form (again in the sense of .expand()). If the main developpers agree on
> this, then you have just located a bug. The coefficients of the result of
> your example look more than a bit unexpanded....

The following patch makes pseries::power_const and pseries::mul_series return expanded series.

Regards

Frieder Kalisch

*** GiNaC-1.3.0/ginac/pseries.cpp.save  2005-01-18 10:13:46.000000000 +0100
--- GiNaC-1.3.0/ginac/pseries.cpp       2005-01-20 12:34:28.000000000 +0100
***************
*** 756,762 ****
ex a_coeff = coeff(var, i);
ex b_coeff = other.coeff(var, cdeg-i);
if (!is_order_function(a_coeff) && !is_order_function(b_coeff))
!                               co += a_coeff * b_coeff;
}
if (!co.is_zero())
new_seq.push_back(expair(co, numeric(cdeg)));
--- 756,762 ----
ex a_coeff = coeff(var, i);
ex b_coeff = other.coeff(var, cdeg-i);
if (!is_order_function(a_coeff) && !is_order_function(b_coeff))
!                               co += (a_coeff * b_coeff).expand();
}
if (!co.is_zero())
new_seq.push_back(expair(co, numeric(cdeg)));
***************
*** 893,906 ****
for (int i=1; i<deg; ++i) {
ex sum = _ex0;
for (int j=1; j<=i; ++j) {
!                       ex c = coeff(var, j + ldeg);
if (is_order_function(c)) {
co.push_back(Order(_ex1));
break;
} else
!                               sum += (p * j - (i - j)) * co[i - j] * c;
}
!               co.push_back(sum / coeff(var, ldeg) / i);
}

// Construct new series (of non-zero coefficients)
--- 893,906 ----
for (int i=1; i<deg; ++i) {
ex sum = _ex0;
for (int j=1; j<=i; ++j) {
!                       ex c = (coeff(var, j + ldeg) / coeff(var, ldeg) / i).expand();
if (is_order_function(c)) {
co.push_back(Order(_ex1));
break;
} else
!                         sum += ((p * j - (i - j)) * co[i - j] * c).expand();
}
!               co.push_back(sum);
}

// Construct new series (of non-zero coefficients)

--
Frieder Kalisch                        Institut für theoretische Physik
kalisch at tphys.uni-heidelberg.de         Philosophenweg 19
+49-6221-549-433                        D-69120 Heidelberg

```