[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.4.3 Comparing structures
The sprod
class defined so far still has one important drawback: all
scalar products are treated as being equal because GiNaC doesn't know how to
compare objects of type sprod_s
. This can lead to some confusing
and undesired behavior:
... cout << make_sprod(a, b) - make_sprod(a*a, b*b) << endl; // -> 0 cout << make_sprod(a, b) + make_sprod(a*a, b*b) << endl; // -> 2*<a|b> or 2*<a^2|b^2> (which one is undefined) ... |
To remedy this, we first need to define the operators ==
and <
for objects of type sprod_s
:
inline bool operator==(const sprod_s & lhs, const sprod_s & rhs) { return lhs.left.is_equal(rhs.left) && lhs.right.is_equal(rhs.right); } inline bool operator<(const sprod_s & lhs, const sprod_s & rhs) { return lhs.left.compare(rhs.left) < 0 ? true : lhs.right.compare(rhs.right) < 0; } |
The ordering established by the <
operator doesn't have to make any
algebraic sense, but it needs to be well defined. Note that we can't use
expressions like lhs.left == rhs.left
or lhs.left < rhs.left
in the implementation of these operators because they would construct
GiNaC relational
objects which in the case of <
do not
establish a well defined ordering (for arbitrary expressions, GiNaC can't
decide which one is algebraically 'less').
Next, we need to change our definition of the sprod
type to let
GiNaC know that an ordering relation exists for the embedded objects:
typedef structure<sprod_s, compare_std_less> sprod; |
sprod
objects then behave as expected:
... cout << make_sprod(a, b) - make_sprod(a*a, b*b) << endl; // -> <a|b>-<a^2|b^2> cout << make_sprod(a, b) + make_sprod(a*a, b*b) << endl; // -> <a|b>+<a^2|b^2> cout << make_sprod(a, b) - make_sprod(a, b) << endl; // -> 0 cout << make_sprod(a, b) + make_sprod(a, b) << endl; // -> 2*<a|b> ... |
The compare_std_less
policy parameter tells GiNaC to use the
std::less
and std::equal_to
functors to compare objects of
type sprod_s
. By default, these functors forward their work to the
standard <
and ==
operators, which we have overloaded.
Alternatively, we could have specialized std::less
and
std::equal_to
for class sprod_s
.
GiNaC provides two other comparison policies for structure<T>
objects: the default compare_all_equal
, and compare_bitwise
which does a bit-wise comparison of the contained T
objects.
This should be used with extreme care because it only works reliably with
built-in integral types, and it also compares any padding (filler bytes of
undefined value) that the T
class might have.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |