X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fpseries.cpp;h=43768179befdd947211e78d9ea1002f7aae430fa;hp=989fda84afd6d6e61acc0c3d25c7f66cacc788e9;hb=f9afb6aca6a971650dff63b11ca8c2ef18506690;hpb=def26469ff96228c66e877bb5594e7d9a24b638f diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 989fda84..43768179 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -4,7 +4,7 @@ * methods for series expansion. */ /* - * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,10 +21,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include - #include "pseries.h" #include "add.h" #include "inifcns.h" // for Order function @@ -38,6 +34,10 @@ #include "archive.h" #include "utils.h" +#include +#include +#include + namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(pseries, basic, @@ -81,8 +81,9 @@ pseries::pseries(const ex &rel_, const epvector &ops_) : seq(ops_) * Archiving */ -pseries::pseries(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) +void pseries::read_archive(const archive_node &n, lst &sym_lst) { + inherited::read_archive(n, sym_lst); archive_node::archive_node_cit first = n.find_first("coeff"); archive_node::archive_node_cit last = n.find_last("power"); ++last; @@ -113,7 +114,6 @@ void pseries::archive(archive_node &n) const n.add_ex("point", point); } -DEFAULT_UNARCHIVE(pseries) ////////// // functions overriding virtual functions from base classes @@ -424,14 +424,12 @@ ex pseries::conjugate() const epvector * newseq = conjugateepvector(seq); ex newpoint = point.conjugate(); - if (!newseq && are_ex_trivially_equal(point, newpoint)) { + if (!newseq && are_ex_trivially_equal(point, newpoint)) { return *this; } ex result = (new pseries(var==newpoint, newseq ? *newseq : seq))->setflag(status_flags::dynallocated); - if (newseq) { - delete newseq; - } + delete newseq; return result; } @@ -1116,6 +1114,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))) @@ -1284,4 +1305,6 @@ ex ex::series(const ex & r, int order, unsigned options) const return e; } +GINAC_BIND_UNARCHIVER(pseries); + } // namespace GiNaC