OpenGM  2.3.x
Discrete Graphical Model Library
typeView.h
Go to the documentation of this file.
1 #ifndef TYPEVIEW_H_
2 #define TYPEVIEW_H_
3 
4 #include <string.h>
5 #include <assert.h>
6 
7 #include <limits>
8 
9 template <class T> class MRFEnergy;
10 
11 template <class GM>
12 class TypeView
13 {
14 private:
15  struct Vector; // node parameters and messages
16  struct Edge; // stores edge information and either forward or backward message
17 
18 public:
19 
20  // types declarations
21  typedef int Label;
22  typedef double REAL;
23  struct GlobalSize; // global information about number of labels
24  struct LocalSize; // local information about number of labels (stored at each node)
25  struct NodeData; // argument to MRFEnergy::AddNode()
26  struct EdgeData; // argument to MRFEnergy::AddEdge()
27 
28 
29  struct GlobalSize
30  {
31 
32  };
33 
34  struct LocalSize // number of labels is stored at MRFEnergy::m_Kglobal
35  {
36  LocalSize(int K);
37 
38  private:
39  friend struct Vector;
40  friend struct Edge;
41  int m_K; // number of labels
42  };
43 
44  struct NodeData
45  {
46  NodeData(const GM& gm, const std::vector<typename GM::IndexType>& factorIDs);
47 
48  private:
49  friend struct Vector;
50  friend struct Edge;
51  const GM& gm_;
52  const std::vector<typename GM::IndexType> factorIDs_;
53  };
54 
55  struct EdgeData
56  {
57 
58  EdgeData(const GM& gm, const typename GM::IndexType factorID);
59 
60  private:
61  friend struct Vector;
62  friend struct Edge;
63  const GM& gm_;
64  const typename GM::IndexType factorID_;
65  };
66 
70 
71 private:
72  friend class MRFEnergy<TypeView<GM> >;
73 
74  struct Vector
75  {
76  static int GetSizeInBytes(GlobalSize Kglobal, LocalSize K); // returns -1 if invalid K's
77  void Initialize(GlobalSize Kglobal, LocalSize K, NodeData data); // called once when user adds a node
78  void Add(GlobalSize Kglobal, LocalSize K, NodeData data); // called once when user calls MRFEnergy::AddNodeData()
79 
80  void SetZero(GlobalSize Kglobal, LocalSize K); // set this[k] = 0
81  void Copy(GlobalSize Kglobal, LocalSize K, Vector* V); // set this[k] = V[k]
82  void Add(GlobalSize Kglobal, LocalSize K, Vector* V); // set this[k] = this[k] + V[k]
83  REAL GetValue(GlobalSize Kglobal, LocalSize K, Label k); // return this[k]
84  REAL ComputeMin(GlobalSize Kglobal, LocalSize K, Label& kMin); // return min_k { this[k] }, set kMin
85  REAL ComputeAndSubtractMin(GlobalSize Kglobal, LocalSize K); // same as previous, but additionally set this[k] -= vMin (and kMin is not returned)
86 
87  static int GetArraySize(GlobalSize Kglobal, LocalSize K);
88  REAL GetArrayValue(GlobalSize Kglobal, LocalSize K, int k); // note: k is an integer in [0..GetArraySize()-1].
89  // For Potts functions GetArrayValue() and GetValue() are the same,
90  // but they are different for, say, 2-dimensional labels.
91  void SetArrayValue(GlobalSize Kglobal, LocalSize K, int k, REAL x);
92 
93  private:
94  friend struct Edge;
95  REAL m_data[1]; // actual size is MRFEnergy::m_Kglobal
96  };
97 
98  struct Edge
99  {
100  static int GetSizeInBytes(GlobalSize Kglobal, LocalSize Ki, LocalSize Kj, EdgeData data); // returns -1 if invalid data
101  static int GetBufSizeInBytes(int vectorMaxSizeInBytes); // returns size of buffer need for UpdateMessage()
102  void Initialize(GlobalSize Kglobal, LocalSize Ki, LocalSize Kj, EdgeData data, Vector* Di, Vector* Dj); // called once when user adds an edge
103  Vector* GetMessagePtr();
104  void Swap(GlobalSize Kglobal, LocalSize Ki, LocalSize Kj); // if the client calls this function, then the meaning of 'dir'
105  // in distance transform functions is swapped
106 
107  // When UpdateMessage() is called, edge contains message from dest to source.
108  // The function must replace it with the message from source to dest.
109  // The update rule is given below assuming that source corresponds to tail (i) and dest corresponds
110  // to head (j) (which is the case if dir==0).
111  //
112  // 1. Compute Di[ki] = gamma*source[ki] - message[ki]. (Note: message = message from j to i).
113  // 2. Compute distance transform: set
114  // message[kj] = min_{ki} (Di[ki] + V(ki,kj)). (Note: message = message from i to j).
115  // 3. Compute vMin = min_{kj} m_message[kj].
116  // 4. Set m_message[kj] -= vMin.
117  // 5. Return vMin.
118  //
119  // If dir==1 then source corresponds to j, sink corresponds to i. Then the update rule is
120  //
121  // 1. Compute Dj[kj] = gamma*source[kj] - message[kj]. (Note: message = message from i to j).
122  // 2. Compute distance transform: set
123  // message[ki] = min_{kj} (Dj[kj] + V(ki,kj)). (Note: message = message from j to i).
124  // 3. Compute vMin = min_{ki} m_message[ki].
125  // 4. Set m_message[ki] -= vMin.
126  // 5. Return vMin.
127  //
128  // If Edge::Swap has been called odd number of times, then the meaning of dir is swapped.
129  //
130  // Vector 'source' must not be modified. Function may use 'buf' as a temporary storage.
131  REAL UpdateMessage(GlobalSize Kglobal, LocalSize Ksource, LocalSize Kdest, Vector* source, REAL gamma, int dir, void* buf);
132 
133  // If dir==0, then sets dest[kj] += V(ksource,kj).
134  // If dir==1, then sets dest[ki] += V(ki,ksource).
135  // If Swap() has been called odd number of times, then the meaning of dir is swapped.
136  void AddColumn(GlobalSize Kglobal, LocalSize Ksource, LocalSize Kdest, Label ksource, Vector* dest, int dir);
137 
138  protected:
139  // edge information
140  const GM* gm_;
141  typename GM::IndexType factorID_;
142 
143  int m_dir; // 0 if Swap() was called even number of times, 1 otherwise
144 
145  // message
146  Vector* m_message;
147  };
148 
149 };
150 
151 
152 
153 
157 
158 template <class GM>
160 {
161  m_K = K;
162 }
163 
165 
166 template <class GM>
167 inline TypeView<GM>::NodeData::NodeData(const GM& gm, const std::vector<typename GM::IndexType>& factorIDs) : gm_(gm), factorIDs_(factorIDs)
168 {
169 
170 }
171 
172 template <class GM>
173 inline TypeView<GM>::EdgeData::EdgeData(const GM& gm, const typename GM::IndexType factorID) : gm_(gm), factorID_(factorID)
174 {
175 
176 }
177 
179 
180 template <class GM>
182 {
183  if (K.m_K < 1)
184  {
185  return -1;
186  }
187  return K.m_K*sizeof(REAL);
188 }
189 
190 template <class GM>
191 inline void TypeView<GM>::Vector::Initialize(GlobalSize Kglobal, LocalSize K, NodeData data)
192 {
193  for (int k=0; k<K.m_K; k++) {
194  m_data[k] = 0.0;
195  for(typename std::vector<typename GM::IndexType>::const_iterator iter = data.factorIDs_.begin(); iter != data.factorIDs_.end(); iter++) {
196  m_data[k] += data.gm_[*iter](&k);
197  }
198  }
199 }
200 
201 template <class GM>
202 inline void TypeView<GM>::Vector::Add(GlobalSize Kglobal, LocalSize K, NodeData data)
203 {
204  for(typename std::vector<typename GM::IndexType>::const_iterator iter = data.factorIDs_.begin(); iter != data.factorIDs_.end(); iter++) {
205  for (int k=0; k<K.m_K; k++)
206  {
207  m_data[k] += data.gm_[*iter](&k);
208  }
209  }
210 }
211 
212 template <class GM>
213 inline void TypeView<GM>::Vector::SetZero(GlobalSize Kglobal, LocalSize K)
214 {
215  memset(m_data, 0, K.m_K*sizeof(REAL));
216 }
217 
218 template <class GM>
219 inline void TypeView<GM>::Vector::Copy(GlobalSize Kglobal, LocalSize K, Vector* V)
220 {
221  memcpy(m_data, V->m_data, K.m_K*sizeof(REAL));
222 }
223 
224 template <class GM>
225 inline void TypeView<GM>::Vector::Add(GlobalSize Kglobal, LocalSize K, Vector* V)
226 {
227  for (int k=0; k<K.m_K; k++)
228  {
229  m_data[k] += V->m_data[k];
230  }
231 }
232 
233 template <class GM>
234 inline typename TypeView<GM>::REAL TypeView<GM>::Vector::GetValue(GlobalSize Kglobal, LocalSize K, Label k)
235 {
236  assert(k>=0 && k<K.m_K);
237  return m_data[k];
238 }
239 
240 template <class GM>
241 inline typename TypeView<GM>::REAL TypeView<GM>::Vector::ComputeMin(GlobalSize Kglobal, LocalSize K, Label& kMin)
242 {
243  REAL vMin = m_data[0];
244  kMin = 0;
245  for (int k=1; k<K.m_K; k++)
246  {
247  if (vMin > m_data[k])
248  {
249  vMin = m_data[k];
250  kMin = k;
251  }
252  }
253 
254  return vMin;
255 }
256 
257 template <class GM>
258 inline typename TypeView<GM>::REAL TypeView<GM>::Vector::ComputeAndSubtractMin(GlobalSize Kglobal, LocalSize K)
259 {
260  REAL vMin = m_data[0];
261  for (int k=1; k<K.m_K; k++)
262  {
263  if (vMin > m_data[k])
264  {
265  vMin = m_data[k];
266  }
267  }
268  for (int k=0; k<K.m_K; k++)
269  {
270  m_data[k] -= vMin;
271  }
272 
273  return vMin;
274 }
275 
276 template <class GM>
277 inline int TypeView<GM>::Vector::GetArraySize(GlobalSize Kglobal, LocalSize K)
278 {
279  return K.m_K;
280 }
281 
282 template <class GM>
283 inline typename TypeView<GM>::REAL TypeView<GM>::Vector::GetArrayValue(GlobalSize Kglobal, LocalSize K, int k)
284 {
285  assert(k>=0 && k<K.m_K);
286  return m_data[k];
287 }
288 
289 template <class GM>
290 inline void TypeView<GM>::Vector::SetArrayValue(GlobalSize Kglobal, LocalSize K, int k, REAL x)
291 {
292  assert(k>=0 && k<K.m_K);
293  m_data[k] = x;
294 }
295 
297 
298 template <class GM>
299 inline int TypeView<GM>::Edge::GetSizeInBytes(GlobalSize Kglobal, LocalSize Ki, LocalSize Kj, EdgeData data)
300 {
301  int messageSizeInBytes = ((Ki.m_K > Kj.m_K) ? Ki.m_K : Kj.m_K)*sizeof(REAL);
302  return sizeof(Edge) + messageSizeInBytes;
303 }
304 
305 template <class GM>
306 inline int TypeView<GM>::Edge::GetBufSizeInBytes(int vectorMaxSizeInBytes)
307 {
308  return 0;
309 }
310 
311 template <class GM>
312 inline void TypeView<GM>::Edge::Initialize(GlobalSize Kglobal, LocalSize Ki, LocalSize Kj, EdgeData data, Vector* Di, Vector* Dj)
313 {
314  gm_ = &data.gm_;
315  factorID_ = data.factorID_;
316 
317  m_dir = 0;
318  m_message = (Vector*)((char*)this + sizeof(Edge));
319  memset(m_message->m_data, 0, ((Ki.m_K > Kj.m_K) ? Ki.m_K : Kj.m_K)*sizeof(REAL));
320 }
321 
322 template <class GM>
324 {
325  return m_message;
326 }
327 
328 template <class GM>
329 inline void TypeView<GM>::Edge::Swap(GlobalSize Kglobal, LocalSize Ki, LocalSize Kj)
330 {
331  m_dir = 1 - m_dir;
332 }
333 
334 template <class GM>
335 inline typename TypeView<GM>::REAL TypeView<GM>::Edge::UpdateMessage(GlobalSize Kglobal, LocalSize Ksource, LocalSize Kdest, Vector* source, REAL gamma, int dir, void* _buf)
336 {
337  Vector* buf = (Vector*) _buf;
338  REAL vMin;
339 
340  int ksource, kdest;
341 
342  for (ksource=0; ksource<Ksource.m_K; ksource++)
343  {
344  buf->m_data[ksource] = gamma*source->m_data[ksource] - m_message->m_data[ksource];
345  }
346 
347  if (dir == m_dir)
348  {
349  for (kdest=0; kdest<Kdest.m_K; kdest++)
350  {
351  typename GM::IndexType index[] = {0, static_cast<typename GM::IndexType>(kdest)};
352  vMin = buf->m_data[0] + (*gm_)[factorID_](index);
353  for (ksource=1; ksource<Ksource.m_K; ksource++)
354  {
355  index[0] = ksource;
356 
357  if (vMin > buf->m_data[ksource] + (*gm_)[factorID_](index))
358  {
359  vMin = buf->m_data[ksource] + (*gm_)[factorID_](index);
360  }
361  }
362  m_message->m_data[kdest] = vMin;
363  }
364  }
365  else
366  {
367  for (kdest=0; kdest<Kdest.m_K; kdest++)
368  {
369  typename GM::IndexType index[] = {static_cast<typename GM::IndexType>(kdest), 0};
370  vMin = buf->m_data[0] + (*gm_)[factorID_](index);
371  for (ksource=1; ksource<Ksource.m_K; ksource++)
372  {
373  index[1] = ksource;
374  if (vMin > buf->m_data[ksource] + (*gm_)[factorID_](index))
375  {
376  vMin = buf->m_data[ksource] + (*gm_)[factorID_](index);
377  }
378  }
379  m_message->m_data[kdest] = vMin;
380  }
381  }
382 
383  vMin = m_message->m_data[0];
384  for (kdest=1; kdest<Kdest.m_K; kdest++)
385  {
386  if (vMin > m_message->m_data[kdest])
387  {
388  vMin = m_message->m_data[kdest];
389  }
390  }
391 
392  for (kdest=0; kdest<Kdest.m_K; kdest++)
393  {
394  m_message->m_data[kdest] -= vMin;
395  }
396 
397  return vMin;
398 }
399 
400 template <class GM>
401 inline void TypeView<GM>::Edge::AddColumn(GlobalSize Kglobal, LocalSize Ksource, LocalSize Kdest, Label ksource, Vector* dest, int dir)
402 {
403  assert(ksource>=0 && ksource<Ksource.m_K);
404 
405  int k;
406 
407  //REAL* data = ((EdgeGeneral*)this)->m_data;
408 
409  if (dir == m_dir)
410  {
411  typename GM::IndexType index[] = {static_cast<typename GM::IndexType>(ksource), 0};
412  for (k=0; k<Kdest.m_K; k++)
413  {
414  index[1] = k;
415  dest->m_data[k] += (*gm_)[factorID_](index);
416  }
417  }
418  else
419  {
420  typename GM::IndexType index[] = {0, static_cast<typename GM::IndexType>(ksource)};
421  for (k=0; k<Kdest.m_K; k++)
422  {
423  index[0] = k;
424  dest->m_data[k] += (*gm_)[factorID_](index);
425  }
426  }
427 }
428 #endif /* TYPEVIEW_H_ */
friend struct Vector
Definition: typeView.h:61
friend struct Vector
Definition: typeView.h:49
friend struct Edge
Definition: typeView.h:40
EdgeData(const GM &gm, const typename GM::IndexType factorID)
Definition: typeView.h:173
int Label
Definition: typeView.h:16
NodeData(const GM &gm, const std::vector< typename GM::IndexType > &factorIDs)
Definition: typeView.h:167
friend struct Edge
Definition: typeView.h:62
friend struct Edge
Definition: typeView.h:50
double REAL
Definition: typeView.h:22
friend struct Vector
Definition: typeView.h:39