vnl_scalar_join_iterator.hxx
Go to the documentation of this file.
1 // This is core/vnl/vnl_scalar_join_iterator.hxx
2 #ifndef vnl_scalar_join_iterator_hxx_
3 #define vnl_scalar_join_iterator_hxx_
4 //:
5 // \file
6 //
7 // \author Andrew W. Fitzgibbon, Oxford RRG
8 // \date 27 Dec 96
9 //
10 //-----------------------------------------------------------------------------
11 
12 #include <list>
13 #include <iostream>
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 
19 #define VNL_SCALAR_JOIN_ITERATOR_INSTANTIATE(T) \
20 template class VNL_EXPORT vnl_scalar_join_iterator_indexed_pair<T >;\
21 template class VNL_EXPORT vnl_scalar_join_iterator<T >; \
22 template VNL_EXPORT std::ostream& operator<<(std::ostream& s, const vnl_scalar_join_iterator_indexed_pair<T >& p);\
23 
24 #include <cassert>
25 #include <vnl/vnl_matrix.h>
26 
27 // Helper class to hold the sorted arrays of indices.
28 
29 template <class T>
32 {
33  return (*that.object) == (*object);
34 }
35 
36 template <class T>
39 {
40  return (*object) < (*that.object);
41 }
42 
43 template <class T>
44 std::ostream& operator<<(std::ostream& s,
46 {
47  return s << p.original_index << ' ' << *(p.object) << '\n';
48 }
49 
50 template <class T>
52  (const vnl_matrix<T>& relation1, unsigned column1,
53  const vnl_matrix<T>& relation2, unsigned column2):
54  n1(relation1.rows()),
55  n2(relation2.rows()),
56  pI1(new std::list<vnl_scalar_join_iterator_indexed_pair<T > >(n1)),
57  pI2(new std::list<vnl_scalar_join_iterator_indexed_pair<T > >(n2)),
58  I1(*pI1),
59  I2(*pI2)
60 {
61  // Sort on appropriate columns
62  {
63  for (unsigned i = 0; i < n1; ++i)
64  I1.push_back(vnl_scalar_join_iterator_indexed_pair<T>(&relation1(i, column1), i));
65  I1.sort();
66  }
67  {
68  for (unsigned i = 0; i < n2; ++i)
69  I2.push_back(vnl_scalar_join_iterator_indexed_pair<T>(&relation2(i, column2), i));
70  I2.sort();
71  }
72 
73  // Initialize for iteration
74  index1 = I1.begin();
75  index2 = I2.begin();
76 
77  // Loop to first
78  for (;;) {
79  T star1 = *(*index1).object;
80  T star2 = *(*index2).object;
81  if (star1 == star2)
82  return;
83 
84  if (star1 > star2)
85  ++index2;
86  else
87  ++index1;
88  }
89 }
90 
91 //: Destructor
92 template <class T>
94 {
95  delete pI1;
96  delete pI2;
97 }
98 
99 template <class T>
101 {
102  return (index1 == I1.end()) || (index2 == I2.end());
103 }
104 
105 //: Increment the iterator to point to the next pair of rows.
106 template <class T>
108 {
109  T obj1 = *(*index1).object;
110  // increment i2, check if still valid/same
111  if (++index2 == I2.end()) return;
112 
113  T nextobj2 = *(*index2).object;
114  if (obj1 == nextobj2)
115  return; // Found another match
116 
117  // nextobj2 must not be < obj1
118  assert(!(nextobj2 < obj1));
119 
120  // So, objects are different (in fact, obj1 > obj2 right now), lockstep until
121  // they match or we're done.
122  while (!done()) {
123  T obj1 = *(*index1).object;
124  T obj2 = *(*index2).object;
125 
126  if (obj1 == obj2) {
127  // If they're equal, hack back along obj2's array to find the start of the
128  // stretch of equal ones. This allows join
129  // 1 3 3 5
130  // 2 3 3 6
131  // to return the kronecker product of the sets by iteration.
132  // No that's going to be a hack. Will be fixed RSN.
133  return;
134  }
135 
136  if (obj1 > obj2)
137  ++index2;
138  else
139  ++index1;
140  }
141 }
142 
143 template <class T>
144 unsigned vnl_scalar_join_iterator<T>::row1() const
145 {
146  return (*index1).original_index;
147 }
148 
149 template <class T>
150 unsigned vnl_scalar_join_iterator<T>::row2() const
151 {
152  return (*index2).original_index;
153 }
154 
155 //: Postfix ++ should not be used. Only present for instantiation purposes.
156 template <class T>
158 {
159  std::cerr << "This should not happen! postfix ++ called\n";
160  return *this;
161 }
162 
163 #endif // vnl_scalar_join_iterator_hxx_
std::list< vnl_scalar_join_iterator_indexed_pair< T > > & I2
vnl_scalar_join_iterator< T > & operator++()
Advance to the next pair. This is prefix ++.
An ordinary mathematical matrix.
Database join on matrix columns.
Database join on matrix columns.
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
Definition: vnl_decnum.h:393
Helper class to hold the sorted arrays of indices.
unsigned row2() const
Return the index of the current row in the second relation.
std::list< vnl_scalar_join_iterator_indexed_pair< T > >::iterator index1
vnl_scalar_join_iterator(const vnl_matrix< T > &relation1, unsigned column1, const vnl_matrix< T > &relation2, unsigned column2)
Initialize this iterator to the join of relation1(:,column1) and relation2(:,column2).
An ordinary mathematical matrix.
Definition: vnl_adjugate.h:22
std::list< vnl_scalar_join_iterator_indexed_pair< T > > & I1
void next()
Increment the iterator to point to the next pair of rows.
std::list< vnl_scalar_join_iterator_indexed_pair< T > >::iterator index2
unsigned row1() const
Return the index of the current row in the first relation.