From: Richard Kreckel Date: Sat, 22 Jul 2000 04:47:04 +0000 (+0000) Subject: - Fixed the bug that broke xloop's po_redux. X-Git-Tag: release_0-6-3~3 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=fe9dbfb9947b24149b3ce7dd9285f27ab286cbd7 - Fixed the bug that broke xloop's po_redux. - Interface Change: No argument 'bool branchcut' for series methods, instead 'unsigned options'. Sorry. : ---------------------------------------------------------------------- --- diff --git a/ginac/add.h b/ginac/add.h index 7db48695..78464d3e 100644 --- a/ginac/add.h +++ b/ginac/add.h @@ -70,7 +70,7 @@ public: int ldegree(const symbol & s) const; ex coeff(const symbol & s, int n=1) const; ex eval(int level=0) const; - ex series(const relational & r, int order, bool branchcut = true) const; + ex series(const relational & r, int order, unsigned options = 0) const; ex normal(lst &sym_lst, lst &repl_lst, int level=0) const; numeric integer_content(void) const; ex smod(const numeric &xi) const; diff --git a/ginac/basic.h b/ginac/basic.h index 2263081c..43fc4958 100644 --- a/ginac/basic.h +++ b/ginac/basic.h @@ -138,7 +138,7 @@ public: // only const functions please (may break reference counting) virtual ex collect(const symbol & s) const; virtual ex eval(int level = 0) const; virtual ex evalf(int level = 0) const; - virtual ex series(const relational & r, int order, bool branchcut = true) const; + virtual ex series(const relational & r, int order, unsigned options = 0) const; virtual ex subs(const lst & ls, const lst & lr) const; virtual ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const; virtual ex to_rational(lst &repl_lst) const; diff --git a/ginac/ex.h b/ginac/ex.h index 05f31573..216a4646 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -252,7 +252,7 @@ public: ex eval(int level = 0) const; ex evalf(int level = 0) const; ex diff(const symbol & s, unsigned nth = 1) const; - ex series(const ex & r, int order, bool branchcut = true) const; + ex series(const ex & r, int order, unsigned options = 0) const; ex subs(const lst & ls, const lst & lr) const; ex subs(const ex & e) const; exvector get_indices(void) const; @@ -395,8 +395,8 @@ inline ex evalf(const ex & thisex, int level = 0) inline ex diff(const ex & thisex, const symbol & s, unsigned nth = 1) { return thisex.diff(s, nth); } -inline ex series(const ex & thisex, const ex & r, int order, bool branchcut = true) -{ return thisex.series(r, order, branchcut); } +inline ex series(const ex & thisex, const ex & r, int order, unsigned options = 0) +{ return thisex.series(r, order, options); } inline ex subs(const ex & thisex, const ex & e) { return thisex.subs(e); } diff --git a/ginac/flags.h b/ginac/flags.h index 8b9caed4..77e3ec01 100644 --- a/ginac/flags.h +++ b/ginac/flags.h @@ -33,6 +33,19 @@ public: }; }; +class series_options { +public: + enum { suppress_branchcut = 0x0001 + }; +}; + +class determinant_options { +public: + enum { laplace, + bareiss + }; +}; + class status_flags { public: enum { dynallocated = 0x0001, @@ -124,7 +137,7 @@ public: enum { delete_never, // let table grow undefinitely, not recommmended, but currently default delete_lru, // least recently used delete_lfu, // least frequently used - delete_cyclic // first one in list (oldest) + delete_cyclic // first (oldest) one in list }; }; diff --git a/ginac/function.pl b/ginac/function.pl index a69f58fe..f67c4b96 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -95,7 +95,7 @@ $typedef_derivative_funcp=generate( 'const ex &',''); $typedef_series_funcp=generate( -'typedef ex (* series_funcp_${N})(${SEQ1}, const relational &, int, bool);'."\n", +'typedef ex (* series_funcp_${N})(${SEQ1}, const relational &, int, unsigned);'."\n", 'const ex &',''); $eval_func_interface=generate(' function_options & eval_func(eval_funcp_${N} e);'."\n",'',''); @@ -145,9 +145,9 @@ $series_switch_statement=generate( <<'END_OF_SERIES_SWITCH_STATEMENT','seq[${N}-1]',''); case ${N}: try { - res = ((series_funcp_${N})(registered_functions()[serial].series_f))(${SEQ1},r,order,branchcut); + res = ((series_funcp_${N})(registered_functions()[serial].series_f))(${SEQ1},r,order,options); } catch (do_taylor) { - res = basic::series(r, order, branchcut); + res = basic::series(r, order, options); } return res; break; @@ -419,7 +419,7 @@ public: ex expand(unsigned options=0) const; ex eval(int level=0) const; ex evalf(int level=0) const; - ex series(const relational & r, int order, bool branchcut = true) const; + ex series(const relational & r, int order, unsigned options = 0) const; ex thisexprseq(const exvector & v) const; ex thisexprseq(exvector * vp) const; protected: @@ -889,7 +889,7 @@ ex function::thisexprseq(exvector * vp) const /** Implementation of ex::series for functions. * \@see ex::series */ -ex function::series(const relational & r, int order, bool branchcut = true) const +ex function::series(const relational & r, int order, unsigned options = 0) const { GINAC_ASSERT(serial=1 (branch cut) - if (ex_to_numeric(x_pt).is_real() && ex_to_numeric(x_pt)>1) { + if (!(options & series_options::suppress_branchcut) && + ex_to_numeric(x_pt).is_real() && ex_to_numeric(x_pt)>1) { // method: // This is the branch cut: assemble the primitive series manually // and then add the corresponding complex step function. @@ -250,7 +251,7 @@ static ex Li2_series(const ex &x, const relational &rel, int order, bool branchc // compute the intermediate terms: ex replarg = series(Li2(x), *s==foo, order); for (unsigned i=1; i(rel.lhs().bp); const ex point = rel.rhs(); const int n = argser.ldegree(*s); @@ -179,12 +179,13 @@ static ex log_series(const ex &arg, seq.push_back(expair(n*log(*s-point), _ex0())); if (!argser.is_terminating() || argser.nops()!=1) { // in this case n more terms are needed - ex newarg = ex_to_pseries(arg.series(rel, order+n, branchcut)).shift_exponents(-n).convert_to_poly(true); - return pseries(rel, seq).add_series(ex_to_pseries(log(newarg).series(rel, order, branchcut))); + ex newarg = ex_to_pseries(arg.series(rel, order+n, options)).shift_exponents(-n).convert_to_poly(true); + return pseries(rel, seq).add_series(ex_to_pseries(log(newarg).series(rel, order, options))); } else // it was a monomial return pseries(rel, seq); } - if (branchcut && arg_pt.info(info_flags::negative)) { + if (!(options & series_options::suppress_branchcut) && + arg_pt.info(info_flags::negative)) { // method: // This is the branch cut: assemble the primitive series manually and // then add the corresponding complex step function. @@ -444,7 +445,7 @@ static ex tan_deriv(const ex & x, unsigned deriv_param) static ex tan_series(const ex &x, const relational &rel, int order, - bool branchcut) + unsigned options) { // method: // Taylor series where there is no pole falls back to tan_deriv. @@ -804,7 +805,7 @@ static ex tanh_deriv(const ex & x, unsigned deriv_param) static ex tanh_series(const ex &x, const relational &rel, int order, - bool branchcut) + unsigned options) { // method: // Taylor series where there is no pole falls back to tanh_deriv. diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index fc9d7e26..feae32fe 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -382,8 +382,8 @@ matrix matrix::mul(const matrix & other) const exvector prod(row*other.col); - for (unsigned r1=0; r1=row || co<0 || co>=col) throw (std::range_error("matrix::operator(): index out of range")); - + return m[ro*col+co]; } @@ -626,9 +626,8 @@ matrix matrix::inverse(void) const throw (std::runtime_error("matrix::inverse(): singular matrix")); } if (indx != 0) { // swap rows r and indx of matrix tmp - for (unsigned i=0; i=0; --r) { unsigned first_non_zero = 1; - while ((first_non_zero<=n)&&(a.m[r*a.cols()+(first_non_zero-1)].is_zero())) + while ((first_non_zero<=n)&&(a(r,first_non_zero-1).is_zero())) first_non_zero++; if (first_non_zero>n) { // row consists only of zeroes, corresponding rhs must be 0 as well - if (!b.m[r*b.cols()].is_zero()) { + if (!b(r,0).is_zero()) { throw (std::runtime_error("matrix::fraction_free_elim(): singular matrix")); } } else { // assign solutions for vars between first_non_zero+1 and // last_assigned_sol-1: free parameters for (unsigned c=first_non_zero; c need not be included: + class range_error; +} + #ifndef NO_NAMESPACE_GINAC namespace GiNaC { #endif // ndef NO_NAMESPACE_GINAC @@ -100,6 +105,7 @@ protected: int division_free_elimination(void); int fraction_free_elimination(bool det = false); int pivot(unsigned ro, bool symbolic=true); + void swap(unsigned r1, unsigned c1, unsigned r2 ,unsigned c2); // member variables protected: @@ -109,10 +115,12 @@ protected: static unsigned precedence; }; + // global constants extern const matrix some_matrix; extern const type_info & typeid_matrix; + // wrapper functions around member functions inline unsigned nops(const matrix & m) diff --git a/ginac/mul.h b/ginac/mul.h index b8409f4d..bfb92366 100644 --- a/ginac/mul.h +++ b/ginac/mul.h @@ -71,7 +71,7 @@ public: ex coeff(const symbol & s, int n = 1) const; ex eval(int level=0) const; ex evalf(int level=0) const; - ex series(const relational & s, int order, bool branchcut = true) const; + ex series(const relational & s, int order, unsigned options = 0) const; ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const; numeric integer_content(void) const; ex smod(const numeric &xi) const; diff --git a/ginac/power.h b/ginac/power.h index 3d8be419..afc59f33 100644 --- a/ginac/power.h +++ b/ginac/power.h @@ -73,7 +73,7 @@ public: ex coeff(const symbol & s, int n = 1) const; ex eval(int level=0) const; ex evalf(int level=0) const; - ex series(const relational & s, int order, bool branchcut = true) const; + ex series(const relational & s, int order, unsigned options = 0) const; ex subs(const lst & ls, const lst & lr) const; ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const; ex to_rational(lst &repl_lst) const; diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 38499480..f55c0fed 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -484,7 +484,7 @@ bool pseries::is_terminating(void) const /** Default implementation of ex::series(). This performs Taylor expansion. * @see ex::series */ -ex basic::series(const relational & r, int order, bool branchcut) const +ex basic::series(const relational & r, int order, unsigned options) const { epvector seq; numeric fac(1); @@ -518,7 +518,7 @@ ex basic::series(const relational & r, int order, bool branchcut) const /** Implementation of ex::series() for symbols. * @see ex::series */ -ex symbol::series(const relational & r, int order, bool branchcut) const +ex symbol::series(const relational & r, int order, unsigned options) const { epvector seq; const ex point = r.rhs(); @@ -615,12 +615,12 @@ ex pseries::add_series(const pseries &other) const /** Implementation of ex::series() for sums. This performs series addition when * adding pseries objects. * @see ex::series */ -ex add::series(const relational & r, int order, bool branchcut) const +ex add::series(const relational & r, int order, unsigned options) const { ex acc; // Series accumulator // Get first term from overall_coeff - acc = overall_coeff.series(r, order, branchcut); + acc = overall_coeff.series(r, order, options); // Add remaining terms epvector::const_iterator it = seq.begin(); @@ -630,7 +630,7 @@ ex add::series(const relational & r, int order, bool branchcut) const if (is_ex_exactly_of_type(it->rest, pseries)) op = it->rest; else - op = it->rest.series(r, order, branchcut); + op = it->rest.series(r, order, options); if (!it->coeff.is_equal(_ex1())) op = ex_to_pseries(op).mul_const(ex_to_numeric(it->coeff)); @@ -720,12 +720,12 @@ ex pseries::mul_series(const pseries &other) const /** Implementation of ex::series() for product. This performs series * multiplication when multiplying series. * @see ex::series */ -ex mul::series(const relational & r, int order, bool branchcut) const +ex mul::series(const relational & r, int order, unsigned options) const { ex acc; // Series accumulator // Get first term from overall_coeff - acc = overall_coeff.series(r, order, branchcut); + acc = overall_coeff.series(r, order, options); // Multiply with remaining terms epvector::const_iterator it = seq.begin(); @@ -738,7 +738,7 @@ ex mul::series(const relational & r, int order, bool branchcut) const acc = ex_to_pseries(acc).mul_const(ex_to_numeric(f)); continue; } else if (!is_ex_exactly_of_type(op, pseries)) - op = op.series(r, order, branchcut); + op = op.series(r, order, options); if (!it->coeff.is_equal(_ex1())) op = ex_to_pseries(op).power_const(ex_to_numeric(it->coeff), order); @@ -810,20 +810,20 @@ pseries pseries::shift_exponents(int deg) const /** Implementation of ex::series() for powers. This performs Laurent expansion * of reciprocals of series at singularities. * @see ex::series */ -ex power::series(const relational & r, int order, bool branchcut) const +ex power::series(const relational & r, int order, unsigned options) const { ex e; if (!is_ex_exactly_of_type(basis, pseries)) { // Basis is not a series, may there be a singulary? if (!exponent.info(info_flags::negint)) - return basic::series(r, order, branchcut); + return basic::series(r, order, options); // Expression is of type something^(-int), check for singularity if (!basis.subs(r).is_zero()) - return basic::series(r, order, branchcut); + return basic::series(r, order, options); // Singularity encountered, expand basis into series - e = basis.series(r, order, branchcut); + e = basis.series(r, order, options); } else { // Basis is a series e = basis; @@ -835,7 +835,7 @@ ex power::series(const relational & r, int order, bool branchcut) const /** Re-expansion of a pseries object. */ -ex pseries::series(const relational & r, int order, bool branchcut) const +ex pseries::series(const relational & r, int order, unsigned options) const { const ex p = r.rhs(); GINAC_ASSERT(is_ex_exactly_of_type(r.lhs(),symbol)); @@ -859,7 +859,7 @@ ex pseries::series(const relational & r, int order, bool branchcut) const return pseries(r, new_seq); } } else - return convert_to_poly().series(r, order, branchcut); + return convert_to_poly().series(r, order, options); } @@ -870,9 +870,9 @@ ex pseries::series(const relational & r, int order, bool branchcut) const * * @param r expansion relation, lhs holds variable and rhs holds point * @param order truncation order of series calculations - * @param branchcut when set to false, branch cuts are not honored + * @param options of class series_options * @return an expression holding a pseries object */ -ex ex::series(const ex & r, int order, bool branchcut) const +ex ex::series(const ex & r, int order, unsigned options) const { GINAC_ASSERT(bp!=0); ex e; @@ -886,7 +886,7 @@ ex ex::series(const ex & r, int order, bool branchcut) const throw (std::logic_error("ex::series(): expansion point has unknown type")); try { - e = bp->series(rel_, order, branchcut); + e = bp->series(rel_, order, options); } catch (std::exception &x) { throw (std::logic_error(std::string("unable to compute series (") + x.what() + ")")); } diff --git a/ginac/pseries.h b/ginac/pseries.h index f7c32aa5..48975724 100644 --- a/ginac/pseries.h +++ b/ginac/pseries.h @@ -67,7 +67,7 @@ public: ex collect(const symbol &s) const; ex eval(int level=0) const; ex evalf(int level=0) const; - ex series(const relational & r, int order, bool branchcut = true) const; + ex series(const relational & r, int order, unsigned options = 0) const; ex subs(const lst & ls, const lst & lr) const; ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const; ex expand(unsigned options = 0) const; diff --git a/ginac/symbol.h b/ginac/symbol.h index 1a51ffb4..bd37892f 100644 --- a/ginac/symbol.h +++ b/ginac/symbol.h @@ -81,7 +81,7 @@ public: int ldegree(const symbol & s) const; ex coeff(const symbol & s, int n = 1) const; ex eval(int level = 0) const; - ex series(const relational & s, int order, bool branchcut = true) const; + ex series(const relational & s, int order, unsigned options = 0) const; ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const; ex to_rational(lst &repl_lst) const; ex subs(const lst & ls, const lst & lr) const;