Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnTableFactorMapping.h
1 /*****************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnTableFactorMapping.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
13 #pragma once
14 
15 #include <cstdlib>
16 #include <cassert>
17 #include <vector>
18 
19 #include "drwnBase.h"
20 #include "drwnIO.h"
21 
22 #include "drwnVarUniverse.h"
23 
24 using namespace std;
25 
28 #define DRWN_FACTOR_MAPPING_FULL
29 #undef DRWN_FACTOR_MAPPING_FULL
30 
31 // drwnTableFactorMapping --------------------------------------------------
38 
40  protected:
42 
43  // the following are not used for identity mappings
44  vector<int> _targetCards;
45  vector<int> _strideMapping;
46 #ifdef DRWN_FACTOR_MAPPING_FULL
47  vector<int> _fullMapping;
48 #endif
49 
50  public:
52  class iterator {
53  protected:
54  friend class drwnTableFactorMapping;
55 
57  int _dstIndx;
58  int _srcIndx;
59  vector<int> _assignment;
60 
61  inline iterator(const drwnTableFactorMapping& m) :
62  _owner(&m), _dstIndx(0), _srcIndx(0) {
63 
64  if (!_owner->identity()) {
65 #ifdef DRWN_FACTOR_MAPPING_FULL
66  if (_owner->_fullMapping.empty())
67 #endif
68  _assignment.resize(_owner->_targetCards.size(), 0);
69  }
70  }
71 
72  inline iterator(const drwnTableFactorMapping& m, size_t indx) :
73  _owner(&m), _dstIndx(indx), _srcIndx(0) {
74 
75  if (_owner->identity()) {
76  _srcIndx = _dstIndx;
77  return;
78  }
79 
80 #ifdef DRWN_FACTOR_MAPPING_FULL
81  // use full mapping if available, otherwise compute srcIndx
82  if (!_owner->_fullMapping.empty()) {
83  _srcIndx = (_dstIndx < (int)_owner->_fullMapping.size()) ?
84  _owner->_fullMapping[_dstIndx] : 0;
85  } else {
86 #else
87  {
88 #endif
89  _assignment.resize(_owner->_targetCards.size(), 0);
90  if (_dstIndx != 0) {
91  int stride = 1;
92  for (unsigned i = 0; i < _assignment.size(); i++) {
93  int r = (int)(_dstIndx / stride);
94  if (r == 0) break;
95  _assignment[i] = r % _owner->_targetCards[i];
96  _srcIndx += r * _owner->_strideMapping[i];
97  stride *= _owner->_targetCards[i];
98  }
99  }
100  }
101  }
102 
103  public:
104  inline iterator() : _owner(NULL), _dstIndx(0), _srcIndx(0) { /* do nothing */ }
105  inline ~iterator() { /* do nothing */ }
106 
107  inline iterator& operator=(const iterator& it) {
108  _owner = it._owner; _dstIndx = it._dstIndx; _srcIndx = it._srcIndx;
109  _assignment = it._assignment;
110  return *this;
111  }
112  inline bool operator==(const iterator& it) const {
113  return ((_owner == it._owner) && (_dstIndx == it._dstIndx));
114  }
115  inline bool operator!=(const iterator& it) const {
116  return (!operator==(it));
117  }
118  inline bool operator<(const iterator& it) const {
119  return (_dstIndx < it._dstIndx);
120  }
121  inline bool operator>(const iterator& it) const {
122  return (_dstIndx > it._dstIndx);
123  }
124  inline bool operator<=(const iterator& it) const {
125  return (_dstIndx <= it._dstIndx);
126  }
127  inline bool operator>=(const iterator& it) const {
128  return (_dstIndx >= it._dstIndx);
129  }
130  inline const int& operator*() const {
131  return _srcIndx;
132  }
133  inline iterator& operator++() {
134  _dstIndx += 1;
135 
136  if (_owner->identity()) {
137  _srcIndx = _dstIndx;
138  return *this;
139  }
140 
141 #ifdef DRWN_FACTOR_MAPPING_FULL
142  if (!_owner->_fullMapping.empty()) {
143  _srcIndx = (_dstIndx < (int)_owner->_fullMapping.size()) ?
144  _owner->_fullMapping[_dstIndx] : 0;
145  return *this;
146  }
147 #endif
148  _assignment[0] += 1;
149  _srcIndx += _owner->_strideMapping[0];
150  for (unsigned i = 1; i < _assignment.size(); i++) {
151  if (_assignment[i - 1] < _owner->_targetCards[i - 1])
152  break;
153  _assignment[i - 1] = 0;
154  _assignment[i] += 1;
155  _srcIndx += _owner->_strideMapping[i];
156  }
157 
158  return *this;
159  }
160 
161  inline iterator& operator--() {
162  _dstIndx -= 1;
163 
164  if (_owner->identity()) {
165  _srcIndx = _dstIndx;
166  return *this;
167  }
168 
169 #ifdef DRWN_FACTOR_MAPPING_FULL
170  if (!_owner->_fullMapping.empty()) {
171  _srcIndx = (_dstIndx >= 0) ? _owner->_fullMapping[_dstIndx] : 0;
172  return *this;
173  }
174 #endif
175  _assignment[0] -= 1;
176  _srcIndx -= _owner->_strideMapping[0];
177  for (unsigned i = 1; i < _assignment.size(); i++) {
178  if (_assignment[i - 1] >= 0)
179  break;
180  _assignment[i - 1] = _owner->_targetCards[i - 1] - 1;
181  _assignment[i] -= 1;
182  _srcIndx -= _owner->_strideMapping[i];
183  }
184  return *this;
185  }
186 
187  inline iterator operator++(int) {
188  iterator copy(*this);
189  ++(*this);
190  return copy;
191  }
192  inline iterator operator--(int) {
193  iterator copy(*this);
194  --(*this);
195  return copy;
196  }
197  inline const int& operator[](int n) const {
198  iterator copy(*_owner, _dstIndx + n);
199  return *copy;
200  }
201  };
202  friend class iterator;
203 
204  public:
206  drwnTableFactorMapping() : _targetSize(0) { /* do nothing */ }
207 
209  drwnTableFactorMapping(const vector<int>& dstVars, const vector<int>& srcVars,
210  const drwnVarUniversePtr& pUniverse) : _targetSize(1) {
211 
212 #if 1
213  // special case: unary source
214  if (srcVars.size() == 1) {
215 
216  // check for identity mapping
217  if (dstVars.size() == 1) {
218  DRWN_ASSERT(dstVars[0] == srcVars[0]);
219  _targetSize = pUniverse->varCardinality(dstVars[0]);
220  return;
221  }
222 
223  // find location of srcVars in dstVars
224  unsigned k = dstVars.size();
225  for (unsigned i = 0; i < dstVars.size(); i++) {
226  if (dstVars[i] == srcVars[0]) k = i;
227  _targetSize *= pUniverse->varCardinality(dstVars[i]);
228  }
229  DRWN_ASSERT(k != dstVars.size());
230 
231  // collapse first and last dstVars into a single variable
232  if (k == 0) {
233  _targetCards.resize(2);
234  _strideMapping.resize(2);
235  _targetCards[0] = pUniverse->varCardinality(srcVars[0]);
236  _targetCards[1] = _targetSize / _targetCards[0];
237  _strideMapping[0] = 1;
238  _strideMapping[1] = -1 * _targetCards[0];
239  } else if (k + 1 == dstVars.size()) {
240  _targetCards.resize(2);
241  _strideMapping.resize(2);
242  _targetCards[1] = pUniverse->varCardinality(srcVars[0]);
243  _targetCards[0] = _targetSize / _targetCards[1];
244  _strideMapping[0] = 0;
245  _strideMapping[1] = 1;
246  } else {
247  _targetCards.resize(3);
248  _strideMapping.resize(3);
249  _targetCards[0] = 1;
250  for (unsigned i = 0; i < k; i++) {
251  _targetCards[0] *= pUniverse->varCardinality(dstVars[i]);
252  }
253  _targetCards[1] = pUniverse->varCardinality(srcVars[0]);
254  _targetCards[2] = _targetSize / (_targetCards[0] * _targetCards[1]);
255  _strideMapping[0] = 0;
256  _strideMapping[1] = 1;
257  _strideMapping[2] = -1 * _targetCards[1];
258  }
259 
260  return;
261  }
262 #endif
263 
264  // check for identity or near identity mappings (first n variables
265  // of dstVars match order of all variables in srcVars)
266  if (std::equal(srcVars.begin(), srcVars.end(), dstVars.begin())) {
267  for (unsigned i = 0; i < dstVars.size(); i++) {
268  _targetSize *= pUniverse->varCardinality(dstVars[i]);
269  }
270 
271  // collapse first srcVars variables into a single variable
272  if (dstVars.size() > srcVars.size()) {
273  _targetCards.resize(2, 1);
274  _strideMapping.resize(2, 1);
275  for (unsigned i = 0; i < srcVars.size(); i++) {
276  _targetCards[0] *= pUniverse->varCardinality(srcVars[i]);
277  }
278  _targetCards[1] = _targetSize / _targetCards[0];
279  _strideMapping[1] = -1 * _targetCards[0];
280  }
281 
282  return;
283  }
284 
285 #if 1
286  // check for near identity mappings on last n variables
287  if ((dstVars.size() > srcVars.size()) &&
288  (std::equal(srcVars.begin(), srcVars.end(), dstVars.end() - srcVars.size()))) {
289  for (unsigned i = 0; i < dstVars.size(); i++) {
290  _targetSize *= pUniverse->varCardinality(dstVars[i]);
291  }
292 
293  // collapse last srcVars variables into a single variable
294  _targetCards.resize(2, 1);
295  _strideMapping.resize(2, 1);
296  for (unsigned i = 0; i < srcVars.size(); i++) {
297  _targetCards[1] *= pUniverse->varCardinality(srcVars[i]);
298  }
299  _targetCards[0] = _targetSize / _targetCards[1];
300  _strideMapping[0] = 0;
301 
302  return;
303  }
304 #endif
305 
306  // build stride index for source variables
308  map<int, unsigned> varIndex;
309  unsigned stride = 1;
310  for (unsigned i = 0; i < srcVars.size(); i++) {
311  varIndex[srcVars[i]] = stride;
312  stride *= pUniverse->varCardinality(srcVars[i]);
313  }
314 
315  _targetCards.resize(dstVars.size(), 0);
316  _strideMapping.resize(dstVars.size(), 0);
317  for (unsigned i = 0; i < dstVars.size(); i++) {
318  _targetCards[i] = pUniverse->varCardinality(dstVars[i]);
319  _targetSize *= _targetCards[i];
320 
321  map<int, unsigned>::const_iterator v = varIndex.find(dstVars[i]);
322  if (v != varIndex.end()) {
323  _strideMapping[i] += v->second;
324  if (i + 1 < dstVars.size()) {
325  _strideMapping[i + 1] = -1 * _targetCards[i] * v->second;
326  }
327  }
328  }
329 
330 #ifdef DRWN_FACTOR_MAPPING_FULL
331  _fullMapping = mapping();
332 #endif
333  }
334  ~drwnTableFactorMapping() { /* do nothing */ }
335 
337  inline bool empty() const { return (_targetSize == 0); }
338 
341  //inline bool identity() const { return (_targetSize != 0) && (_targetCards.empty()); }
342  inline bool identity() const { return _targetCards.empty(); }
343 
345  iterator begin() const { return iterator(*this); }
346  iterator end() const { return iterator(*this, _targetSize); }
347 
349  vector<int> mapping() const {
350  vector<int> m;
351  m.reserve(_targetSize);
352  for (iterator it = begin(); it != end(); ++it) {
353  m.push_back(*it);
354  }
355  return m;
356  }
357 };
bool identity() const
returns true if the mapping is identity (destiation variables and source variables are in the same or...
Definition: drwnTableFactorMapping.h:342
vector< int > mapping() const
returns the mapping of indexes from the source to the destiation
Definition: drwnTableFactorMapping.h:349
const drwnTableFactorMapping * _owner
the factor mapping that owns this iterator
Definition: drwnTableFactorMapping.h:56
bool empty() const
returns true if the mapping has size zero
Definition: drwnTableFactorMapping.h:337
iterator begin() const
iterators
Definition: drwnTableFactorMapping.h:345
vector< int > _assignment
current assignement to the variables in the target table
Definition: drwnTableFactorMapping.h:59
int varCardinality(int v) const
returns the cardinality of variable v (between 0 and _numVariables - 1)
Definition: drwnVarUniverse.h:51
drwnTableFactorMapping(const vector< int > &dstVars, const vector< int > &srcVars, const drwnVarUniversePtr &pUniverse)
dstVar is a superset of srcVar (and variables don't repeat)
Definition: drwnTableFactorMapping.h:209
drwnTableFactorMapping()
default constructor
Definition: drwnTableFactorMapping.h:206
bool operator<(const CvSize &r, const CvSize &s)
inequality operator for CvSize objects (allows partial sorting)
Definition: drwnOpenCVUtils.cpp:88
Creates a mapping between entries in two tables.
Definition: drwnTableFactorMapping.h:39
int _dstIndx
current index into the target table
Definition: drwnTableFactorMapping.h:57
vector< int > _strideMapping
stride mapping from source to target
Definition: drwnTableFactorMapping.h:45
vector< int > _targetCards
cardinality of each variable in the target
Definition: drwnTableFactorMapping.h:44
int _srcIndx
current index into the source table
Definition: drwnTableFactorMapping.h:58
int _targetSize
number of entries in the target table
Definition: drwnTableFactorMapping.h:41
iterator for indexing entries in the tables
Definition: drwnTableFactorMapping.h:52
bool operator==(const CvRect &r, const CvRect &s)
equality operator for CvRect objects
Definition: drwnOpenCVUtils.cpp:83