diff --git a/src/db/db/dbArray.h b/src/db/db/dbArray.h index 78e7fd402..a5e1222ca 100644 --- a/src/db/db/dbArray.h +++ b/src/db/db/dbArray.h @@ -115,8 +115,12 @@ struct ArrayBase virtual bool equal (const ArrayBase *) const = 0; + virtual bool fuzzy_equal (const ArrayBase *) const = 0; + virtual bool less (const ArrayBase *) const = 0; + virtual bool fuzzy_less (const ArrayBase *) const = 0; + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const = 0; bool in_repository; @@ -558,6 +562,12 @@ struct regular_array return (m_a == d->m_a && m_b == d->m_b && m_amax == d->m_amax && m_bmax == d->m_bmax); } + virtual bool fuzzy_equal (const ArrayBase *b) const + { + const regular_array *d = static_cast *> (b); + return (m_a.equal (d->m_a) && m_b.equal (d->m_b) && m_amax == d->m_amax && m_bmax == d->m_bmax); + } + virtual bool less (const ArrayBase *b) const { const regular_array *d = static_cast *> (b); @@ -566,6 +576,14 @@ struct regular_array m_amax < d->m_amax || (m_amax == d->m_amax && m_bmax < d->m_bmax))))); } + virtual bool fuzzy_less (const ArrayBase *b) const + { + const regular_array *d = static_cast *> (b); + return m_a.less (d->m_a) || (m_a.equal (d->m_a) && ( + m_b.less (d->m_b) || (m_b.equal (d->m_b) && ( + m_amax < d->m_amax || (m_amax == d->m_amax && m_bmax < d->m_bmax))))); + } + virtual bool is_regular_array (vector_type &a, vector_type &b, unsigned long &amax, unsigned long &bmax) const { a = m_a; @@ -706,6 +724,18 @@ struct regular_complex_array return regular_array::equal (b); } + virtual bool fuzzy_equal (const ArrayBase *b) const + { + const regular_complex_array *d = static_cast *> (b); + if (fabs (m_acos - d->m_acos) > epsilon) { + return false; + } + if (fabs (m_mag - d->m_mag) > epsilon) { + return false; + } + return regular_array::fuzzy_equal (b); + } + virtual bool less (const ArrayBase *b) const { const regular_complex_array *d = static_cast *> (b); @@ -718,6 +748,18 @@ struct regular_complex_array return regular_array::less (b); } + virtual bool fuzzy_less (const ArrayBase *b) const + { + const regular_complex_array *d = static_cast *> (b); + if (fabs (m_acos - d->m_acos) > epsilon) { + return m_acos < d->m_acos; + } + if (fabs (m_mag - d->m_mag) > epsilon) { + return m_mag < d->m_mag; + } + return regular_array::fuzzy_less (b); + } + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { if (!no_self) { @@ -983,6 +1025,20 @@ struct iterated_array return true; } + virtual bool fuzzy_equal (const ArrayBase *b) const + { + const iterated_array *d = static_cast *> (b); + if (m_v.size () != d->m_v.size ()) { + return false; + } + for (const_iterator p1 = m_v.begin (), p2 = d->m_v.begin (); p1 != m_v.end (); ++p1, ++p2) { + if (! p1->equal (*p2)) { + return false; + } + } + return true; + } + virtual bool less (const ArrayBase *b) const { const iterated_array *d = static_cast *> (b); @@ -997,6 +1053,20 @@ struct iterated_array return false; } + virtual bool fuzzy_less (const ArrayBase *b) const + { + const iterated_array *d = static_cast *> (b); + if (m_v.size () != d->m_v.size ()) { + return (m_v.size () < d->m_v.size ()); + } + for (const_iterator p1 = m_v.begin (), p2 = d->m_v.begin (); p1 != m_v.end (); ++p1, ++p2) { + if (! p1->equal (*p2)) { + return (p1->less (*p2)); + } + } + return false; + } + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { if (!no_self) { @@ -1104,6 +1174,18 @@ struct iterated_complex_array return iterated_array::equal (b); } + virtual bool fuzzy_equal (const ArrayBase *b) const + { + const iterated_complex_array *d = static_cast *> (b); + if (fabs (m_acos - d->m_acos) > epsilon) { + return false; + } + if (fabs (m_mag - d->m_mag) > epsilon) { + return false; + } + return iterated_array::fuzzy_equal (b); + } + virtual bool less (const ArrayBase *b) const { const iterated_complex_array *d = static_cast *> (b); @@ -1116,6 +1198,18 @@ struct iterated_complex_array return iterated_array::less (b); } + virtual bool fuzzy_less (const ArrayBase *b) const + { + const iterated_complex_array *d = static_cast *> (b); + if (fabs (m_acos - d->m_acos) > epsilon) { + return m_acos < d->m_acos; + } + if (fabs (m_mag - d->m_mag) > epsilon) { + return m_mag < d->m_mag; + } + return iterated_array::fuzzy_less (b); + } + virtual complex_trans_type complex_trans (const simple_trans_type &s) const { return complex_trans_type (s, m_acos, m_mag); @@ -1206,7 +1300,12 @@ struct single_complex_inst return true; } - virtual bool less (const ArrayBase *b) const + virtual bool fuzzy_equal (const ArrayBase *b) const + { + return equal (b); + } + + virtual bool less (const ArrayBase *b) const { const double epsilon = 1e-10; const single_complex_inst *d = static_cast *> (b); @@ -1219,6 +1318,11 @@ struct single_complex_inst return false; } + virtual bool fuzzy_less (const ArrayBase *b) const + { + return less (b); + } + virtual void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const { if (!no_self) { @@ -2019,6 +2123,21 @@ struct array } } + /** + * @brief Compare operator for equality (fuzzy version) + */ + bool equal (const array &d) const + { + if (! mp_base) { + return (m_trans.equal (d.m_trans) && m_obj == d.m_obj && ! d.mp_base); + } else { + if (! m_trans.equal (d.m_trans) || ! (m_obj == d.m_obj) || type () != d.type ()) { + return false; + } + return mp_base && mp_base->fuzzy_equal (d.mp_base); + } + } + /** * @brief A sorting order criterion */ @@ -2044,6 +2163,31 @@ struct array } } + /** + * @brief A fuzzy sorting order criterion + */ + bool less (const array &d) const + { + if (! (m_obj == d.m_obj)) { + return (m_obj < d.m_obj); + } + if (! m_trans.equal (d.m_trans)) { + return m_trans.less (d.m_trans); + } + if (type () != d.type ()) { + return (type () < d.type ()); + } + if (mp_base == d.mp_base) { + return false; + } else if (! mp_base) { + return true; + } else if (! d.mp_base) { + return false; + } else { + return mp_base->fuzzy_less (d.mp_base); + } + } + /** * @brief Compare operator * diff --git a/src/db/db/gsiDeclDbCell.cc b/src/db/db/gsiDeclDbCell.cc index d6f2bef9d..a0ff3b0f6 100644 --- a/src/db/db/gsiDeclDbCell.cc +++ b/src/db/db/gsiDeclDbCell.cc @@ -371,17 +371,17 @@ struct cell_inst_array_defs static bool less (const C *i, const C &other) { - return *i < other; + return i->less (other); } static bool equal (const C *i, const C &other) { - return *i == other; + return i->equal (other); } static bool not_equal (const C *i, const C &other) { - return ! equal (i, other); + return ! i->equal (other); } static gsi::Methods methods (bool new_doc) diff --git a/testdata/ruby/dbCellInstArrayTest.rb b/testdata/ruby/dbCellInstArrayTest.rb index 7f2e03f4d..fb61fedc7 100644 --- a/testdata/ruby/dbCellInstArrayTest.rb +++ b/testdata/ruby/dbCellInstArrayTest.rb @@ -81,9 +81,9 @@ class DBCellInst_TestClass < TestBase assert_equal(at.trans.to_s, "r90 0,0") assert_equal(at.cplx_trans.to_s, "r135 *1 0,0") - assert_equal(at < a, true) + assert_equal(at < a, false) assert_equal(at < atdup, false) - assert_equal(a < at, false) + assert_equal(a < at, true) assert_equal(atdup < at, false) assert_equal(a != at, true) assert_equal(a == at, false) @@ -143,9 +143,9 @@ class DBCellInst_TestClass < TestBase assert_equal(at.cplx_trans.to_s, "r135 *1 0,0") assert_equal(at.to_s, "#0 r135 *1 0,0 [-20,10*3;-40,30*5]") - assert_equal(at < a, true) + assert_equal(at < a, false) assert_equal(at < atdup, false) - assert_equal(a < at, false) + assert_equal(a < at, true) assert_equal(atdup < at, false) assert_equal(a != at, true) assert_equal(a == at, false) @@ -210,9 +210,9 @@ class DBCellInst_TestClass < TestBase assert_equal(at.trans.to_s, "r90 0,0") assert_equal(at.cplx_trans.to_s, "r135 *1 0,0") - assert_equal(at < a, true) + assert_equal(at < a, false) assert_equal(at < atdup, false) - assert_equal(a < at, false) + assert_equal(a < at, true) assert_equal(atdup < at, false) assert_equal(a != at, true) assert_equal(a == at, false) @@ -272,9 +272,9 @@ class DBCellInst_TestClass < TestBase assert_equal(at.cplx_trans.to_s, "r135 *1 0,0") assert_equal(at.to_s, "#0 r135 *1 0,0 [-20,10*3;-40,30*5]") - assert_equal(at < a, true) + assert_equal(at < a, false) assert_equal(at < atdup, false) - assert_equal(a < at, false) + assert_equal(a < at, true) assert_equal(atdup < at, false) assert_equal(a != at, true) assert_equal(a == at, false)