Add method relational::canonical().
authorVladimir V. Kisil <V.Kisilv@leeds.ac.uk>
Sun, 8 Aug 2021 14:18:31 +0000 (16:18 +0200)
committerRichard Kreckel <kreckel@ginac.de>
Sun, 8 Aug 2021 14:18:31 +0000 (16:18 +0200)
It returns an equivalent relation with the zero right-hand side.

doc/tutorial/ginac.texi
ginac/relational.cpp
ginac/relational.h

index 40fa562493db280cce75c18d1f6afc4c3ccfec47..d52e422b8c6c295a2ca052c4c198599e6f3612fc 100644 (file)
@@ -1866,13 +1866,31 @@ substitutions.  They are also used as arguments to the @code{ex::series}
 method, where the left hand side of the relation specifies the variable
 to expand in and the right hand side the expansion point.  They can also
 be used for creating systems of equations that are to be solved for
 method, where the left hand side of the relation specifies the variable
 to expand in and the right hand side the expansion point.  They can also
 be used for creating systems of equations that are to be solved for
-unknown variables.  But the most common usage of objects of this class
+unknown variables.
+
+But the most common usage of objects of this class
 is rather inconspicuous in statements of the form @code{if
 (expand(pow(a+b,2))==a*a+2*a*b+b*b) @{...@}}.  Here, an implicit
 conversion from @code{relational} to @code{bool} takes place.  Note,
 however, that @code{==} here does not perform any simplifications, hence
 @code{expand()} must be called explicitly.
 
 is rather inconspicuous in statements of the form @code{if
 (expand(pow(a+b,2))==a*a+2*a*b+b*b) @{...@}}.  Here, an implicit
 conversion from @code{relational} to @code{bool} takes place.  Note,
 however, that @code{==} here does not perform any simplifications, hence
 @code{expand()} must be called explicitly.
 
+Simplifications of
+relationals may be more efficient if preceded by a call to
+@example
+ex relational::canonical() const
+@end example
+which returns an equivalent relation with the zero
+right-hand side. For example:
+@example
+possymbol p("p");
+relational rel = (p >= (p*p-1)/p);
+if (ex_to<relational>(rel.canonical().normal()))
+       cout << "correct inequality" << endl;
+@end example
+However, a user shall not expect that any inequality can be fully
+resolved by GiNaC.
+
 @node Integrals, Matrices, Relations, Basic concepts
 @c    node-name, next, previous, up
 @section Integrals
 @node Integrals, Matrices, Relations, Basic concepts
 @c    node-name, next, previous, up
 @section Integrals
index 892d2e911e123afe0b6832f7b8a3edc213b718cf..d050b2e65fffc14c143cccd35bfc9ddf62412ac5 100644 (file)
@@ -348,4 +348,11 @@ relational::operator relational::safe_bool() const
        }
 }
 
        }
 }
 
+/** Returns an equivalent relational with zero right-hand side.
+ */
+ex relational::canonical() const
+{
+       return relational(lh-rh, _ex0, o);
+}
+
 } // namespace GiNaC
 } // namespace GiNaC
index b935a7edd5c21adfcb60c6a74c928f61df6d3a8d..a9b072a78068e368c71dad4b5815b5f78f294b46 100644 (file)
@@ -63,6 +63,8 @@ public:
        void archive(archive_node& n) const override;
        /** Read (a.k.a. deserialize) object from archive. */
        void read_archive(const archive_node& n, lst& syms) override;
        void archive(archive_node& n) const override;
        /** Read (a.k.a. deserialize) object from archive. */
        void read_archive(const archive_node& n, lst& syms) override;
+       ex canonical() const;
+
 protected:
        ex eval_ncmul(const exvector & v) const override;
        bool match_same_type(const basic & other) const override;
 protected:
        ex eval_ncmul(const exvector & v) const override;
        bool match_same_type(const basic & other) const override;