00001 #ifndef vnl_scalar_join_iterator_h_ 00002 #define vnl_scalar_join_iterator_h_ 00003 // This is vxl/vnl/vnl_scalar_join_iterator.h 00004 00005 //: 00006 // \file 00007 // \brief Database join on matrix columns 00008 // \author Andrew W. Fitzgibbon, Oxford RRG, 27 Dec 96 00009 // \verbatim 00010 // vnl_scalar_join_iterator implements a fast database join on columns 00011 // of matrices of scalars. "Scalar" here really means that the 00012 // objects have comparison operators. The cost is O(n log n) where 00013 // n is the number of rows, all for the two sorts in the ctor. 00014 // 00015 // CAVEAT: The current implementation fudges multiple occurrences 00016 // of the same key in the source column. For example, 00017 // 00018 // join 1 3 and 3 5 on columns 2 and 1 respectively 00019 // 2 3 3 6 00020 // should give 00021 // 1 3 3 5 00022 // 1 3 3 6 00023 // 2 3 3 5 00024 // 2 3 3 6 00025 // And it doesn't. Contact awf if you need this to work. 00026 // 00027 // \endverbatim 00028 // 00029 00030 // 00031 // Modifications: 00032 // LSB (Manchester) Documentation Tidied 00033 // 00034 //----------------------------------------------------------------------------- 00035 00036 #include <vcl_list.h> 00037 #include <vnl/vnl_matrix.h> 00038 00039 template <class T> 00040 class vnl_scalar_join_iterator_indexed_pair; 00041 00042 //: Database join on matrix columns. 00043 00044 template <class T> 00045 class vnl_scalar_join_iterator { 00046 public: 00047 00048 //: Initialize this iterator to the join of 00049 // relation1(:,column1) and relation2(:,column2). 00050 // The algorithm sorts an array of pointers to each row and 00051 // traversal of the iterator runs through these to produce the join. 00052 // After construction the row1() and row2() methods indicate the first pair. 00053 vnl_scalar_join_iterator(const vnl_matrix<T>& relation1, unsigned column1, 00054 const vnl_matrix<T>& relation2, unsigned column2); 00055 00056 ~vnl_scalar_join_iterator(); 00057 00058 00059 //: Return true if all pairs have been seen. 00060 operator bool () { return !done(); } 00061 00062 //: Advance to the next pair. This is prefix ++. 00063 inline vnl_scalar_join_iterator<T>& operator ++ () { next(); return *this; } 00064 00065 bool done(); 00066 void next(); 00067 00068 //: Return the indices of the current rows in the first and second relations. 00069 unsigned row1(); 00070 //: Return the indices of the current rows in the first and second relations. 00071 unsigned row2(); 00072 00073 private: 00074 // Postfix ++ is private as it would be costly to implement. 00075 vnl_scalar_join_iterator<T>& operator ++ (int); 00076 00077 //T object1() { return *I1[index1].object; } 00078 //T object2() { return *I2[index2].object; } 00079 00080 protected: 00081 unsigned n1; 00082 unsigned n2; 00083 vcl_list<vnl_scalar_join_iterator_indexed_pair<T> >* pI1; 00084 vcl_list<vnl_scalar_join_iterator_indexed_pair<T> >* pI2; 00085 vcl_list<vnl_scalar_join_iterator_indexed_pair<T> >& I1; 00086 vcl_list<vnl_scalar_join_iterator_indexed_pair<T> >& I2; 00087 vcl_list<vnl_scalar_join_iterator_indexed_pair<T> >::iterator index1; 00088 vcl_list<vnl_scalar_join_iterator_indexed_pair<T> >::iterator index2; 00089 }; 00090 00091 //: Helper class to hold the sorted arrays of indices. 00092 template <class T> 00093 struct vnl_scalar_join_iterator_indexed_pair { 00094 public: 00095 const T* object; 00096 int original_index; 00097 00098 vnl_scalar_join_iterator_indexed_pair() {} 00099 vnl_scalar_join_iterator_indexed_pair(const T* object_, int original_index_):object(object_), original_index(original_index_) {} 00100 00101 bool operator == (const vnl_scalar_join_iterator_indexed_pair<T>& that) const; 00102 bool operator < (const vnl_scalar_join_iterator_indexed_pair<T>& that) const; 00103 00104 }; 00105 00106 #endif // vnl_scalar_join_iterator_h_