mul::info(): cache the result of the positiveness/negativeness checks, ...
authorAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Sun, 13 Oct 2013 10:16:16 +0000 (13:16 +0300)
committerAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Wed, 16 Oct 2013 05:20:29 +0000 (08:20 +0300)
... and use the cached result if possible.

check/CMakeLists.txt
check/check_mul_info.cpp [new file with mode: 0644]
ginac/mul.cpp

index 0445a4a..42fe50e 100644 (file)
@@ -6,6 +6,7 @@ set(ginac_tests
        check_inifcns
        check_matrices
        check_lsolve
        check_inifcns
        check_matrices
        check_lsolve
+       check_mul_info
        heur_gcd_bug
        exam_paranoia
        exam_heur_gcd
        heur_gcd_bug
        exam_paranoia
        exam_heur_gcd
diff --git a/check/check_mul_info.cpp b/check/check_mul_info.cpp
new file mode 100644 (file)
index 0000000..34652f8
--- /dev/null
@@ -0,0 +1,14 @@
+#include "ginac.h"
+#include <iostream>
+using namespace GiNaC;
+
+int main(int argc, char** argv)
+{
+       symbol x("x"), y("y");
+       ex e = x*y;
+       if (!e.info(info_flags::indefinite)) {
+               std::cerr << "eek, product of two symbols is NOT indefinite";
+               return 1;
+       }
+       return 0;
+}
index cee5cd7..64660a2 100644 (file)
@@ -307,6 +307,13 @@ bool mul::info(unsigned inf) const
                }
                case info_flags::positive:
                case info_flags::negative: {
                }
                case info_flags::positive:
                case info_flags::negative: {
+                       if ((inf==info_flags::positive) && (flags & status_flags::is_positive))
+                               return true;
+                       else if ((inf==info_flags::negative) && (flags & status_flags::is_negative))
+                               return true;
+                       if (flags & status_flags::purely_indefinite)
+                               return false;
+
                        bool pos = true;
                        epvector::const_iterator i = seq.begin(), end = seq.end();
                        while (i != end) {
                        bool pos = true;
                        epvector::const_iterator i = seq.begin(), end = seq.end();
                        while (i != end) {
@@ -320,9 +327,12 @@ bool mul::info(unsigned inf) const
                        }
                        if (overall_coeff.info(info_flags::negative))
                                pos = !pos;
                        }
                        if (overall_coeff.info(info_flags::negative))
                                pos = !pos;
-                       return (inf ==info_flags::positive? pos : !pos);
+                       setflag(pos ? status_flags::is_positive : status_flags::is_negative);
+                       return (inf == info_flags::positive? pos : !pos);
                }
                case info_flags::nonnegative: {
                }
                case info_flags::nonnegative: {
+                       if  (flags & status_flags::is_positive)
+                               return true;
                        bool pos = true;
                        epvector::const_iterator i = seq.begin(), end = seq.end();
                        while (i != end) {
                        bool pos = true;
                        epvector::const_iterator i = seq.begin(), end = seq.end();
                        while (i != end) {
@@ -373,6 +383,21 @@ bool mul::info(unsigned inf) const
                                return false;
                        return pos; 
                }
                                return false;
                        return pos; 
                }
+               case info_flags::indefinite: {
+                       if (flags & status_flags::purely_indefinite)
+                               return true;
+                       if (flags & (status_flags::is_positive | status_flags::is_negative))
+                               return false;
+                       epvector::const_iterator i = seq.begin(), end = seq.end();
+                       while (i != end) {
+                               const ex& term = recombine_pair_to_ex(*i);
+                               if (term.info(info_flags::positive) || term.info(info_flags::negative))
+                                       return false;
+                               ++i;
+                       }
+                       setflag(status_flags::purely_indefinite);
+                       return true;
+               }
        }
        return inherited::info(inf);
 }
        }
        return inherited::info(inf);
 }