X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Finifcns.cpp;h=ec74a435de0774290f6d95baa221690b87420de7;hb=fa1ffcfdc9da97a6fb7cc2c9c36fe1fc45c808a9;hp=4e426f4ca3d097abe0ab7cb84381d0f5d4442d6a;hpb=63f3e977f92d51ea173382a9b7c4c3b18bda7b8e;p=ginac.git diff --git a/ginac/inifcns.cpp b/ginac/inifcns.cpp index 4e426f4c..ec74a435 100644 --- a/ginac/inifcns.cpp +++ b/ginac/inifcns.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's initially known functions. */ /* - * GiNaC Copyright (C) 1999-2018 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2020 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 @@ -321,6 +321,8 @@ static ex abs_expand(const ex & arg, unsigned options) static ex abs_expl_derivative(const ex & arg, const symbol & s) { ex diff_arg = arg.diff(s); + if (arg.info(info_flags::real)) + return diff_arg*(2*step(arg) - 1); return (diff_arg*arg.conjugate()+arg*diff_arg.conjugate())/2/abs(arg); } @@ -1038,6 +1040,29 @@ REGISTER_FUNCTION(Order, eval_func(Order_eval). // Solve linear system ////////// +class symbolset { + exset s; + void insert_symbols(const ex &e) + { + if (is_a(e)) { + s.insert(e); + } else { + for (const ex &sube : e) { + insert_symbols(sube); + } + } + } +public: + explicit symbolset(const ex &e) + { + insert_symbols(e); + } + bool has(const ex &e) const + { + return s.find(e) != s.end(); + } +}; + ex lsolve(const ex &eqns, const ex &symbols, unsigned options) { // solve a system of linear equations @@ -1053,20 +1078,20 @@ ex lsolve(const ex &eqns, const ex &symbols, unsigned options) } // syntax checks - if (!eqns.info(info_flags::list)) { - throw(std::invalid_argument("lsolve(): 1st argument must be a list or an equation")); + if (!(eqns.info(info_flags::list) || eqns.info(info_flags::exprseq))) { + throw(std::invalid_argument("lsolve(): 1st argument must be a list, a sequence, or an equation")); } for (size_t i=0; i(symbols.op(c)),1); linpart -= co*symbols.op(c); sys(r,c) = co; @@ -1088,11 +1116,13 @@ ex lsolve(const ex &eqns, const ex &symbols, unsigned options) } // test if system is linear and fill vars matrix + const symbolset sys_syms(sys); + const symbolset rhs_syms(rhs); for (size_t i=0; i