[GiNaC-devel] [PATCH 1/4] Improve info(info_flags::has_indices), introduce flags to cache the result.

Alexei Sheplyakov varg at theor.jinr.ru
Mon Sep 17 15:18:24 CEST 2007


info(info_flags::has_indices) now works for sums and products. It
returns true if the expression has indices (no matter dummy or free),
and false otherwise.

---
 ginac/expairseq.cpp |   23 +++++++++++++++++++++--
 ginac/flags.h       |    4 +++-
 ginac/idx.cpp       |    7 +++++--
 ginac/power.cpp     |   15 +++++++++++++++
 ginac/symbol.cpp    |   35 +++++++++++++++++++----------------
 5 files changed, 63 insertions(+), 21 deletions(-)

diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp
index 757f3c3..79c741a 100644
--- a/ginac/expairseq.cpp
+++ b/ginac/expairseq.cpp
@@ -24,6 +24,7 @@
 #include <algorithm>
 #include <string>
 #include <stdexcept>
+#include <iterator>
 
 #include "expairseq.h"
 #include "lst.h"
@@ -267,8 +268,26 @@ void expairseq::do_print_tree(const print_tree & c, unsigned level) const
 
 bool expairseq::info(unsigned inf) const
 {
-	if (inf == info_flags::expanded)
-		return (flags & status_flags::expanded);
+	switch(inf) {
+		case info_flags::expanded:
+			return (flags & status_flags::expanded);
+		case info_flags::has_indices: {
+			if (flags & status_flags::has_indices)
+				return true;
+			else if (flags & status_flags::has_no_indices)
+				return false;
+			for (epvector::const_iterator i = seq.begin(); i != seq.end(); ++i) {
+				if (i->rest.info(info_flags::has_indices)) {
+					this->setflag(status_flags::has_indices);
+					this->clearflag(status_flags::has_no_indices);
+					return true;
+				}
+			}
+			this->clearflag(status_flags::has_indices);
+			this->setflag(status_flags::has_no_indices);
+			return false;
+		}
+	}
 	return inherited::info(inf);
 }
 
diff --git a/ginac/flags.h b/ginac/flags.h
index 86d8238..372b899 100644
--- a/ginac/flags.h
+++ b/ginac/flags.h
@@ -193,7 +193,9 @@ public:
 		evaluated       = 0x0002, ///< .eval() has already done its job
 		expanded        = 0x0004, ///< .expand(0) has already done its job (other expand() options ignore this flag)
 		hash_calculated = 0x0008, ///< .calchash() has already done its job
-		not_shareable   = 0x0010  ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare())
+		not_shareable   = 0x0010, ///< don't share instances of this object between different expressions unless explicitly asked to (used by ex::compare())
+		has_indices	= 0x0020,
+		has_no_indices	= 0x0040  // ! (has_indices || has_no_indices) means "don't know"
 	};
 };
 
diff --git a/ginac/idx.cpp b/ginac/idx.cpp
index 3e17569..e966b14 100644
--- a/ginac/idx.cpp
+++ b/ginac/idx.cpp
@@ -234,8 +234,11 @@ void spinidx::do_print_tree(const print_tree & c, unsigned level) const
 
 bool idx::info(unsigned inf) const
 {
-	if (inf == info_flags::idx)
-		return true;
+	switch(inf) {
+		case info_flags::idx:
+		case info_flags::has_indices:
+			return true;
+	}
 	return inherited::info(inf);
 }
 
diff --git a/ginac/power.cpp b/ginac/power.cpp
index b490b8c..fe7132a 100644
--- a/ginac/power.cpp
+++ b/ginac/power.cpp
@@ -240,6 +240,21 @@ bool power::info(unsigned inf) const
 			       basis.info(inf);
 		case info_flags::expanded:
 			return (flags & status_flags::expanded);
+		case info_flags::has_indices: {
+			if (flags & status_flags::has_indices)
+				return true;
+			else if (flags & status_flags::has_no_indices)
+				return false;
+			else if (basis.info(info_flags::has_indices)) {
+				setflag(status_flags::has_indices);
+				clearflag(status_flags::has_no_indices);
+				return true;
+			} else {
+				clearflag(status_flags::has_indices);
+				setflag(status_flags::has_no_indices);
+				return false;
+			}
+		}
 	}
 	return inherited::info(inf);
 }
diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp
index 9f3b1c6..b68fed8 100644
--- a/ginac/symbol.cpp
+++ b/ginac/symbol.cpp
@@ -207,22 +207,25 @@ void symbol::do_print_python_repr(const print_python_repr & c, unsigned level) c
 
 bool symbol::info(unsigned inf) const
 {
-	if (inf == info_flags::symbol)
-		return true;
-	if (inf == info_flags::polynomial ||
-	    inf == info_flags::integer_polynomial ||
-	    inf == info_flags::cinteger_polynomial ||
-	    inf == info_flags::rational_polynomial ||
-	    inf == info_flags::crational_polynomial ||
-	    inf == info_flags::rational_function ||
-			inf == info_flags::expanded)
-		return true;
-	if (inf == info_flags::real)
-		return domain==domain::real || domain==domain::positive;
-	if (inf == info_flags::positive || inf == info_flags::nonnegative)
-		return domain == domain::positive;
-	else
-		return inherited::info(inf);
+	switch (inf) {
+		case info_flags::symbol:
+		case info_flags::polynomial:
+		case info_flags::integer_polynomial: 
+		case info_flags::cinteger_polynomial: 
+		case info_flags::rational_polynomial: 
+		case info_flags::crational_polynomial: 
+		case info_flags::rational_function: 
+		case info_flags::expanded:
+			return true;
+		case info_flags::real:
+			return domain == domain::real || domain == domain::positive;
+		case info_flags::positive:
+		case info_flags::nonnegative:
+			return domain == domain::positive;
+		case info_flags::has_indices:
+			return false;
+	}
+	return inherited::info(inf);
 }
 
 ex symbol::eval(int level) const
-- 
1.5.2.4

Best regards,
  Alexei

-- 
All science is either physics or stamp collecting.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20070917/000a56cc/attachment.pgp


More information about the GiNaC-devel mailing list