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@tphys.uni-heidelberg.de Philosophenweg 19 +49-6221-549-433 D-69120 Heidelberg