]> www.ginac.de Git - ginac.git/blobdiff - ginac/ex.cpp
Happy New Year!
[ginac.git] / ginac / ex.cpp
index a5ede054b13eeb35ebb3b50fc90d4b3166a04a94..73a3ba79239e7b8b34ba111416110c6b66f8430d 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's light-weight expression handles. */
 
 /*
- *  GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2019 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
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <iostream>
-#include <stdexcept>
-
 #include "ex.h"
 #include "add.h"
 #include "mul.h"
 #include "ncmul.h"
 #include "numeric.h"
+#include "matrix.h"
 #include "power.h"
 #include "lst.h"
 #include "relational.h"
-#include "input_lexer.h"
 #include "utils.h"
 
+#include <iostream>
+#include <stdexcept>
+
 namespace GiNaC {
 
 //////////
@@ -94,7 +94,7 @@ ex ex::diff(const symbol & s, unsigned nth) const
 /** Check whether expression matches a specified pattern. */
 bool ex::match(const ex & pattern) const
 {
-       lst repl_lst;
+       exmap repl_lst;
        return bp->match(pattern, repl_lst);
 }
 
@@ -102,12 +102,10 @@ bool ex::match(const ex & pattern) const
  *  the "found" list. If the expression itself matches the pattern, the
  *  children are not further examined. This function returns true when any
  *  matches were found. */
-bool ex::find(const ex & pattern, lst & found) const
+bool ex::find(const ex & pattern, exset& found) const
 {
        if (match(pattern)) {
-               found.append(*this);
-               found.sort();
-               found.unique();
+               found.insert(*this);
                return true;
        }
        bool any_found = false;
@@ -125,7 +123,7 @@ ex ex::subs(const lst & ls, const lst & lr, unsigned options) const
 
        // Convert the lists to a map
        exmap m;
-       for (lst::const_iterator its = ls.begin(), itr = lr.begin(); its != ls.end(); ++its, ++itr) {
+       for (auto its = ls.begin(), itr = lr.begin(); its != ls.end(); ++its, ++itr) {
                m.insert(std::make_pair(*its, *itr));
 
                // Search for products and powers in the expressions to be substituted
@@ -142,7 +140,7 @@ ex ex::subs(const lst & ls, const lst & lr, unsigned options) const
 /** Substitute objects in an expression (syntactic substitution) and return
  *  the result as a new expression.  There are two valid types of
  *  replacement arguments: 1) a relational like object==ex and 2) a list of
- *  relationals lst(object1==ex1,object2==ex2,...). */
+ *  relationals lst{object1==ex1,object2==ex2,...}. */
 ex ex::subs(const ex & e, unsigned options) const
 {
        if (e.info(info_flags::relation_equal)) {
@@ -164,8 +162,7 @@ ex ex::subs(const ex & e, unsigned options) const
                // Argument is a list: convert it to a map
                exmap m;
                GINAC_ASSERT(is_a<lst>(e));
-               for (lst::const_iterator it = ex_to<lst>(e).begin(); it != ex_to<lst>(e).end(); ++it) {
-                       ex r = *it;
+               for (auto & r : ex_to<lst>(e)) {
                        if (!r.info(info_flags::relation_equal))
                                throw(std::invalid_argument("basic::subs(ex): argument must be a list of equations"));
                        const ex & s = r.op(0);
@@ -205,7 +202,7 @@ void ex::traverse_postorder(visitor & v) const
        accept(v);
 }
 
-/** Return modifyable operand/member at position i. */
+/** Return modifiable operand/member at position i. */
 ex & ex::let_op(size_t i)
 {
        makewriteable();
@@ -240,6 +237,31 @@ ex ex::rhs() const
        return bp->op(1);
 }
 
+/** Check whether expression is a polynomial. */
+bool ex::is_polynomial(const ex & vars) const
+{
+       if (is_a<lst>(vars)) {
+               const lst & varlst = ex_to<lst>(vars);
+               for (auto & it : varlst)
+                       if (!bp->is_polynomial(it))
+                               return false;
+               return true;
+       }
+       else
+               return bp->is_polynomial(vars);
+}
+
+/** Check whether expression is zero or zero matrix. */
+bool ex::is_zero_matrix() const
+{
+       if (is_zero())
+               return  true;
+       else {
+               ex e = evalm();
+               return is_a<matrix>(e) && ex_to<matrix>(e).is_zero_matrix();
+       }
+}
+
 // private
 
 /** Make this ex writable (if more than one ex handle the same basic) by 
@@ -284,7 +306,7 @@ ptr<basic> ex::construct_from_basic(const basic & other)
                // apply eval() once more. The recursion stops when eval() calls
                // hold() or returns an object that already has its "evaluated"
                // flag set, such as a symbol or a numeric.
-               const ex & tmpex = other.eval(1);
+               const ex & tmpex = other.eval();
 
                // Eventually, the eval() recursion goes through the "else" branch
                // below, which assures that the object pointed to by tmpex.bp is
@@ -379,10 +401,7 @@ basic & ex::construct_from_int(int i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
@@ -416,10 +435,7 @@ basic & ex::construct_from_uint(unsigned int i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
@@ -477,10 +493,7 @@ basic & ex::construct_from_long(long i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
@@ -514,32 +527,15 @@ basic & ex::construct_from_ulong(unsigned long i)
        case 12:
                return *const_cast<numeric *>(_num12_p);
        default:
-               basic *bp = new numeric(i);
-               bp->setflag(status_flags::dynallocated);
-               GINAC_ASSERT(bp->get_refcount() == 0);
-               return *bp;
+               return dynallocate<numeric>(i);
        }
 }
        
 basic & ex::construct_from_double(double d)
 {
-       basic *bp = new numeric(d);
-       bp->setflag(status_flags::dynallocated);
-       GINAC_ASSERT(bp->get_refcount() == 0);
-       return *bp;
+       return dynallocate<numeric>(d);
 }
 
-ptr<basic> ex::construct_from_string_and_lst(const std::string &s, const ex &l)
-{
-       set_lexer_string(s);
-       set_lexer_symbols(l);
-       ginac_yyrestart(NULL);
-       if (ginac_yyparse())
-               throw (std::runtime_error(get_parser_error()));
-       else
-               return parsed_ex.bp;
-}
-       
 //////////
 // static member variables
 //////////