contrib/oxl/mvl/PairMatchMulti.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/PairMatchMulti.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 //  \file
00007 
00008 #include "PairMatchMulti.h"
00009 
00010 #include <vcl_cassert.h>
00011 #include <vcl_fstream.h>
00012 #include <vcl_utility.h>
00013 
00014 #include <vbl/vbl_sparse_array_2d.h>
00015 #include <vnl/vnl_matrix.h>
00016 #include <mvl/PairMatchSet.h>
00017 
00018 typedef vbl_sparse_array_2d<double> hack ;
00019 
00020 vcl_multimap_uint_uint::iterator vcl_multimap_uint_uint::insert(unsigned key, unsigned value)
00021 {
00022   return base::insert(vcl_pair<const unsigned, unsigned>(key, value));
00023 }
00024 
00025 void vcl_multimap_uint_uint::clear() { base::erase(begin(), end()); }
00026 
00027 //: Default constructor
00028 PairMatchMulti::PairMatchMulti()
00029 {
00030   scores_ = 0;
00031 }
00032 
00033 // - Construct and load matches (via operator>>) from vcl_istream.
00034 PairMatchMulti::PairMatchMulti(vcl_istream& f)
00035 {
00036   scores_ = 0;
00037   f >> *this;
00038 }
00039 
00040 //: Copy ctor
00041 PairMatchMulti::PairMatchMulti(const PairMatchMulti& that)
00042 {
00043   scores_ = 0;
00044   operator=(that);
00045 }
00046 
00047 //: Assignment
00048 PairMatchMulti& PairMatchMulti::operator=(const PairMatchMulti& that)
00049 {
00050   matches12_ = that.matches12_;
00051   delete scores_; scores_ = 0;
00052   if (that.scores_)
00053     scores_ = new vbl_sparse_array_2d<double>(*that.scores_);
00054   return *this;
00055 }
00056 
00057 //: Destructor
00058 PairMatchMulti::~PairMatchMulti()
00059 {
00060   delete scores_; scores_ = 0;
00061 }
00062 
00063 void PairMatchMulti::add_match(int i1, int i2, double score)
00064 {
00065   add_match(i1, i2);
00066   set_score(i1, i2, score);
00067 }
00068 
00069 void PairMatchMulti::set_score(int i1, int i2, double score)
00070 {
00071   if (!scores_)
00072     scores_ = new vbl_sparse_array_2d<double>;
00073 
00074   scores_->put(i1, i2, score);
00075 }
00076 
00077 bool PairMatchMulti::contains(int i1, int i2) const
00078 {
00079   for (vcl_multimap_uint_uint::const_iterator p = matches12_.lower_bound(i1); p != matches12_.upper_bound(i1); ++p)
00080     if ((*p).second == (unsigned)i2)
00081       return true;
00082   return false;
00083 }
00084 
00085 double PairMatchMulti::get_score(int i1, int i2) const
00086 {
00087   if (scores_ == 0)
00088     return -1.0;
00089 
00090   double* p = scores_->get_addr(i1, i2);
00091   if (p == 0)
00092     return -1.0;
00093 
00094   return *p;
00095 }
00096 
00097 vcl_ostream& operator << (vcl_ostream& s, const PairMatchMulti& pm)
00098 {
00099   for (PairMatchMultiIterator p(pm); p; ++p) {
00100     int i1 = p.get_i1();
00101     int i2 = p.get_i2();
00102     double score = pm.get_score(i1, i2);
00103 
00104     s << i1 << ' ' << i2;
00105     if (score != -1)
00106       s << "   " << score;
00107     s << vcl_endl;
00108   }
00109   return s;
00110 }
00111 
00112 static int dbl2int(double d)
00113 {
00114   int i = (int)d;
00115   if ((double)i != d)
00116     vcl_cerr << "PairMatchMulti: WARNING: saw double " << d << ", expected int.\n";
00117   return i;
00118 }
00119 
00120 vcl_istream& operator >> (vcl_istream& s, PairMatchMulti& pm)
00121 {
00122   // why do we bother trying to do things properly...
00123   pm.read_ascii(s);
00124   //if (!pm.read_ascii(s)) s.setstate(ios::failbit);
00125   return s;
00126 }
00127 
00128 bool PairMatchMulti::read_ascii(vcl_istream& s)
00129 {
00130   vnl_matrix<double> m;
00131   s >> m;
00132   if (!(s.good() || s.eof())) {
00133     vcl_cerr << "PairMatchMulti load failed\n";
00134     return false;
00135   }
00136 
00137   int cols = m.columns();
00138   if (cols != 2 && cols != 3) {
00139     vcl_cerr << "PairMatchMulti load failed: Saw " << cols << " data per line, expected 2 or 3\n";
00140     return false;
00141   }
00142 
00143 
00144   int n = m.rows();
00145   for (int i = 0; i < n; ++i) {
00146     int i1 = dbl2int(m(i,0));
00147     int i2 = dbl2int(m(i,1));
00148     if (cols == 3) {
00149       double score = m(i,2);
00150       add_match(i1, i2, score);
00151     } else
00152       add_match(i1, i2, 0.0);
00153   }
00154   assert(count() == n);
00155 
00156   // vcl_cerr << "PairMatchMulti load: read " << count() << " matches\n";
00157 
00158   return true;
00159 }
00160 
00161 bool PairMatchMulti::is_superset(PairMatchSet& matches)
00162 {
00163   bool allok = true;
00164   for (PairMatchSet::iterator p = matches; p; ++p) {
00165     int i1 = p.get_i1();
00166     int i2 = p.get_i2();
00167     bool ok = false;
00168     for (PairMatchMultiIterator i = get_match_12(i1); i; ++i)
00169       if (i.get_i2() == i2) {
00170         ok = true;
00171         break;
00172       }
00173     if (!ok) {
00174       allok = false;
00175       break;
00176     }
00177   }
00178 
00179   if (allok)
00180     return true;
00181   else {
00182     vcl_cerr << "PairMatchMulti::is_superset() -- it ain't\n";
00183     for (PairMatchSet::iterator p = matches; p; ++p) {
00184       int i1 = p.get_i1();
00185       int i2 = p.get_i2();
00186       vcl_cerr << i1 << ": [" << i2 << "] ";
00187       bool ok = false;
00188       for (PairMatchMultiIterator i = get_match_12(i1); i; ++i) {
00189         vcl_cerr << i.get_i2() << " ";
00190         if (i.get_i2() == i2) ok = true;
00191       }
00192       if (!ok)
00193         vcl_cerr << "!!!!!";
00194       vcl_cerr << vcl_endl;
00195     }
00196     return false;
00197   }
00198 }
00199 
00200 //: load from ascii file
00201 bool PairMatchMulti::load(char const* filename)
00202 {
00203   vcl_ifstream f(filename);
00204   if (!f.good()) {
00205     vcl_cerr << "PairMatchMulti: Error opening " << filename << vcl_endl;
00206     return false;
00207   }
00208   f >> *this;
00209   return true;
00210 }
00211 
00212 #ifdef TEST_PairMatchMulti
00213 #include <vcl_iostream.h>
00214 
00215 main()
00216 {
00217   PairMatchMulti mm;
00218   mm.add_match(1,2);
00219   mm.add_match(2,2);
00220   mm.add_match(1,3);
00221   mm.add_match(7,2);
00222 
00223   mm.add_match(1,4);
00224   mm.add_match(3,5);
00225   mm.add_match(3,2);
00226 
00227   vcl_cerr << "All matches, sorted:\n";
00228   for (PairMatchMulti::match_iterator p(mm); !p.done(); p.next())
00229     vcl_cerr << p.get_i1() << " " << p.get_i2() << vcl_endl;
00230 
00231   for (int target = 1; target <= 7; ++target) {
00232     vcl_cerr << "Matches for " << target << vcl_endl;
00233     for (PairMatchMulti::match_iterator p = mm.get_match_12(target); !p.done(); p.next())
00234       vcl_cerr << p.get_i1() << " " << p.get_i2() << vcl_endl;
00235   }
00236 }
00237 #endif