Read@CVL
GCoptimization.h
Go to the documentation of this file.
1 /*
2 ##############################################################################
3 # #
4 # GCoptimization - software for energy minimization with graph cuts #
5 # Version 3.0 #
6 # http://www.csd.uwo.ca/faculty/olga/software.html #
7 # #
8 # Copyright 2007-2010 Olga Veksler (olga@csd.uwo.ca) #
9 # Andrew Delong (andrew.delong@gmail.com) #
10 # #
11 ##############################################################################
12 
13  C++ requires at least Visual C++ 2005 (VC8) or GCC 4.03. Supports 32 or 64-bit.
14  See matlab/README.TXT for bundled MATLAB wrapper and its documentation.
15 
16  IMPORTANT:
17  To use this software, YOU MUST CITE the following in any resulting publication:
18 
19  [1] Efficient Approximate Energy Minimization via Graph Cuts.
20  Y. Boykov, O. Veksler, R.Zabih. IEEE TPAMI, 20(12):1222-1239, Nov 2001.
21 
22  [2] What Energy Functions can be Minimized via Graph Cuts?
23  V. Kolmogorov, R.Zabih. IEEE TPAMI, 26(2):147-159, Feb 2004.
24 
25  [3] An Experimental Comparison of Min-Cut/Max-Flow Algorithms for
26  Energy Minimization in Vision. Y. Boykov, V. Kolmogorov.
27  IEEE TPAMI, 26(9):1124-1137, Sep 2004.
28 
29  Furthermore, if you use the label cost feature (setLabelCost), you should cite
30 
31  [4] Fast Approximate Energy Minimization with Label Costs.
32  A. Delong, A. Osokin, H. N. Isack, Y. Boykov. In CVPR, June 2010.
33 
34  This software can be used only for research purposes. For commercial purposes,
35  be aware that there is a US patent on the main algorithm itself:
36 
37  R. Zabih, Y. Boykov, O. Veksler,
38  "System and method for fast approximate energy minimization via graph cuts",
39  United Stated Patent 6,744,923, June 1, 2004
40 
41  Together with this library implemented by O. Veksler, we provide, with the
42  permission of the V. Kolmogorov and Y. Boykov, the following two libraries:
43 
44  1) energy.h
45  Developed by V. Kolmogorov, this implements the binary energy minimization
46  technique described in [2] above. We use this to implement the binary
47  energy minimization step for the alpha-expansion and swap algorithms.
48  The graph construction provided by "energy.h" is more efficient than
49  the original graph construction for alpha-expansion described in [1].
50 
51  Again, this software can be used only for research purposes. IF YOU USE
52  THIS SOFTWARE (energy.h), YOU SHOULD CITE THE AFOREMENTIONED PAPER [2]
53  IN ANY RESULTING PUBLICATION.
54 
55  2) maxflow.cpp, graph.cpp, graph.h, block.h
56  Developed by Y. Boykov and V. Kolmogorov while at Siemens Corporate Research,
57  algorithm [3] was later reimplemented by V. Kolmogorov based on open publications
58  and we use his implementation here with permission.
59 
60  If you use either of these libraries for research purposes, you should cite
61  the aforementioned papers in any resulting publication.
62 
63 ##################################################################
64 
65  License & disclaimer.
66 
67  Copyright 2007-2010 Olga Veksler <olga@csd.uwo.ca>
68  Andrew Delong <andrew.delong@gmail.com>
69 
70  This software and its modifications can be used and distributed for
71  research purposes only. Publications resulting from use of this code
72  must cite publications according to the rules given above. Only
73  Olga Veksler has the right to redistribute this code, unless expressed
74  permission is given otherwise. Commercial use of this code, any of
75  its parts, or its modifications is not permited. The copyright notices
76  must not be removed in case of any modifications. This Licence
77  commences on the date it is electronically or physically delivered
78  to you and continues in effect unless you fail to comply with any of
79  the terms of the License and fail to cure such breach within 30 days
80  of becoming aware of the breach, in which case the Licence automatically
81  terminates. This Licence is governed by the laws of Canada and all
82  disputes arising from or relating to this Licence must be brought
83  in Toronto, Ontario.
84 
85  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
86  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
87  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
88  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
89  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
90  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
91  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
92  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
93  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
95  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96 
97 ##################################################################
98 */
99 
100 #ifndef __GCOPTIMIZATION_H__
101 #define __GCOPTIMIZATION_H__
102 // Due to quiet bugs in function template specialization, it is not
103 // safe to use earlier MS compilers.
104 #if defined(_MSC_VER) && _MSC_VER < 1400
105 #error Requires Visual C++ 2005 (VC8) compiler or later.
106 #endif
107 
108 // diem: compiler warnings
109 #ifdef _MSC_VER
110 #pragma warning(push, 0) // no warnings from includes
111 #pragma warning(disable: 4706) // assignment within conditional expression
112 #pragma warning(disable:4701) // potentially uninitialized local variable used
113 #elif __GNUC__
114 #pragma GCC diagnostic push
115 #pragma GCC diagnostic ignored "-Wreorder"
116 #endif
117 
118 #include <cstddef>
119 #include "energy.h"
120 #include "graph.cpp"
121 #include "maxflow.cpp"
122 
124 // Utility functions, classes, and macros
126 
127 class GCException {
128 public:
129  const char* message;
130  GCException( const char* m ): message(m) { }
131  void Report();
132 };
133 
134 #ifdef _WIN32
135 typedef __int64 gcoclock_t;
136 #else
137 #include <ctime>
138 typedef clock_t gcoclock_t;
139 #endif
140 extern "C" gcoclock_t gcoclock(); // fairly high-resolution timer... better than clock() when available
141 extern "C" gcoclock_t GCO_CLOCKS_PER_SEC; // this variable will stay 0 until gcoclock() is called for the first time
142 
143 #ifdef _MSC_EXTENSIONS
144 #define OLGA_INLINE __forceinline
145 #else
146 #define OLGA_INLINE inline
147 #endif
148 
149 #ifndef GCO_MAX_ENERGYTERM
150 #define GCO_MAX_ENERGYTERM 10000000 // maximum safe coefficient to avoid integer overflow
151  // if a data/smooth/label cost term is larger than this,
152  // the library will raise an exception
153 #endif
154 
155 #if defined(GCO_ENERGYTYPE) && !defined(GCO_ENERGYTERMTYPE)
156 #define GCO_ENERGYTERMTYPE GCO_ENERGYTYPE
157 #endif
158 #if !defined(GCO_ENERGYTYPE) && defined(GCO_ENERGYTERMTYPE)
159 #define GCO_ENERGYTYPE GCO_ENERGYTERMTYPE
160 #endif
161 
162 
164 // GCoptimization class
166 class LinkedBlockList;
167 
169 {
170 public:
171 #ifdef GCO_ENERGYTYPE
172  typedef GCO_ENERGYTYPE EnergyType;
173  typedef GCO_ENERGYTERMTYPE EnergyTermType;
174 #else
175 #ifdef GCO_ENERGYTYPE32
176  typedef int EnergyType; // 32-bit energy total
177 #else
178  typedef long long EnergyType; // 64-bit energy total
179 #endif
180  typedef int EnergyTermType; // 32-bit energy terms
181 #endif
184  typedef int LabelID; // Type for labels
185  typedef VarID SiteID; // Type for sites
186  typedef EnergyTermType (*SmoothCostFn)(SiteID s1, SiteID s2, LabelID l1, LabelID l2);
187  typedef EnergyTermType (*DataCostFn)(SiteID s, LabelID l);
188  typedef EnergyTermType (*SmoothCostFnExtra)(SiteID s1, SiteID s2, LabelID l1, LabelID l2,void *);
189  typedef EnergyTermType (*DataCostFnExtra)(SiteID s, LabelID l,void *);
190 
191  GCoptimization(SiteID num_sites, LabelID num_labels);
192  virtual ~GCoptimization();
193 
194  // Peforms expansion algorithm. Runs the number of iterations specified by max_num_iterations
195  // If no input specified,runs until convergence. Returns total energy of labeling.
196  EnergyType expansion(int max_num_iterations=-1);
197 
198  // Peforms expansion on one label, specified by the input parameter alpha_label
199  bool alpha_expansion(LabelID alpha_label);
200 
201  // Peforms swap algorithm. Runs it the specified number of iterations. If no
202  // input is specified,runs until convergence
203  EnergyType swap(int max_num_iterations=-1);
204 
205  // Peforms swap on a pair of labels, specified by the input parameters alpha_label, beta_label
206  void alpha_beta_swap(LabelID alpha_label, LabelID beta_label);
207 
208  // Peforms swap on a pair of labels, specified by the input parameters alpha_label, beta_label
209  // only on the sitess in the specified arrays, alphaSites and betaSitess, and the array sizes
210  // are, respectively, alpha_size and beta_size
211  void alpha_beta_swap(LabelID alpha_label, LabelID beta_label, SiteID *alphaSites,
212  SiteID alpha_size, SiteID *betaSites, SiteID beta_size);
213 
214  struct DataCostFunctor; // use this class to pass a functor to setDataCost
215  struct SmoothCostFunctor; // use this class to pass a functor to setSmoothCost
216 
217  // Set cost for all (SiteID,LabelID) pairs. Default data cost is all zeros.
218  void setDataCost(DataCostFn fn);
219  void setDataCost(DataCostFnExtra fn, void *extraData);
220  void setDataCost(EnergyTermType *dataArray);
221  void setDataCost(SiteID s, LabelID l, EnergyTermType e);
222  void setDataCostFunctor(DataCostFunctor* f);
224  virtual EnergyTermType compute(SiteID s, LabelID l) = 0;
225  };
226  // Set cost of assigning 'l' to a specific subset of sites.
227  // The sites are listed as (SiteID,cost) pairs.
228  struct SparseDataCost {
229  SiteID site;
230  EnergyTermType cost;
231  };
232  void setDataCost(LabelID l, SparseDataCost *costs, SiteID count);
233 
234  // Set cost for all (LabelID,LabelID) pairs; the actual smooth cost is then weighted
235  // at each pair of on neighbors. Defaults to Potts model (0 if l1==l2, 1 otherwise)
236  void setSmoothCost(SmoothCostFn fn);
237  void setSmoothCost(SmoothCostFnExtra fn, void *extraData);
238  void setSmoothCost(LabelID l1, LabelID l2, EnergyTermType e);
239  void setSmoothCost(EnergyTermType *smoothArray);
240  void setSmoothCostFunctor(SmoothCostFunctor* f);
242  virtual EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2) = 0;
243  };
244 
245  // Sets the cost of using label in the solution.
246  // Set either as uniform cost, or an individual per-label cost.
247  void setLabelCost(EnergyTermType cost);
248  void setLabelCost(EnergyTermType* costArray);
249  void setLabelSubsetCost(LabelID* labels, LabelID numLabels, EnergyTermType cost);
250 
251  // Returns current label assigned to input site
252  LabelID whatLabel(SiteID site);
253  void whatLabel(SiteID start, SiteID count, LabelID* labeling);
254 
255  // This function can be used to change the label of any site at any time
256  void setLabel(SiteID site, LabelID label);
257 
258  // setLabelOrder(false) sets the order to be not random; setLabelOrder(true)
259  // sets the order to random. By default, the labels are visited in non-random order
260  // for both the swap and alpha-expansion moves
261  // Note that srand() must be initialized with an appropriate seed in order for
262  // random order to take effect!
263  void setLabelOrder(bool isRandom);
264  void setLabelOrder(const LabelID* order, LabelID size);
265 
266  // Returns total energy for the current labeling
267  EnergyType compute_energy();
268 
269  // Returns separate Data, Smooth, and Label energy of current labeling
270  EnergyType giveDataEnergy();
271  EnergyType giveSmoothEnergy();
272  EnergyType giveLabelEnergy();
273 
274  // Returns number of sites/labels as specified in the constructor
275  SiteID numSites() const;
276  LabelID numLabels() const;
277 
278  // Prints output to stdout during exansion/swap execution.
279  // 0 => no output
280  // 1 => cycle-level output (cycle number, current energy)
281  // 2 => expansion-/swap-level output (label(s), current energy)
282  void setVerbosity(int level) { m_verbosity = level; }
283 
284 protected:
285  struct LabelCost {
286  ~LabelCost() { delete [] labels; }
287  EnergyTermType cost;
288  bool active; // flag indicates if this particular labelcost is in effect (i.e. wrt m_labeling)
289  VarID aux;
290  LabelCost* next; // global list of LabelSetCost records
291  LabelID numLabels;
292  LabelID* labels;
293  };
294 
295  struct LabelCostIter {
297  LabelCostIter* next; // local list of LabelSetCost records that contain this label
298  };
299 
300  LabelID m_num_labels;
301  SiteID m_num_sites;
302  LabelID *m_labeling;
303  SiteID *m_lookupSiteVar; // holds index of variable corresponding to site participating in a move,
304  // -1 for nonparticipating site
305  LabelID *m_labelTable; // to figure out label order in which to do expansion/swaps
309  EnergyTermType* m_datacostIndividual;
310  EnergyTermType* m_smoothcostIndividual;
311  EnergyTermType* m_labelingDataCosts;
312  SiteID* m_labelCounts;
319 
323 
324  SiteID *m_numNeighbors; // holds num of neighbors for each site
325  SiteID m_numNeighborsTotal; // holds total num of neighbor relationships
326 
327  EnergyType (GCoptimization::*m_giveSmoothEnergyInternal)();
328  SiteID (GCoptimization::*m_queryActiveSitesExpansion)(LabelID, SiteID*);
329  void (GCoptimization::*m_setupDataCostsExpansion)(SiteID,LabelID,EnergyT*,SiteID*);
330  void (GCoptimization::*m_setupSmoothCostsExpansion)(SiteID,LabelID,EnergyT*,SiteID*);
331  void (GCoptimization::*m_setupDataCostsSwap)(SiteID,LabelID,LabelID,EnergyT*,SiteID*);
332  void (GCoptimization::*m_setupSmoothCostsSwap)(SiteID,LabelID,LabelID,EnergyT*,SiteID*);
333  void (GCoptimization::*m_applyNewLabeling)(EnergyT*,SiteID*,SiteID,LabelID);
334  void (GCoptimization::*m_updateLabelingDataCosts)();
335 
336  void (*m_datacostFnDelete)(void* f);
337  void (*m_smoothcostFnDelete)(void* f);
338  bool (GCoptimization::*m_solveSpecialCases)(EnergyType&);
339 
340  // returns a pointer to the neighbors of a site and the weights
341  virtual void giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights)=0;
342  virtual void finalizeNeighbors() = 0;
343 
345  DataCostFnFromArray(EnergyTermType* theArray, LabelID num_labels)
346  : m_array(theArray), m_num_labels(num_labels){}
347  OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l){return m_array[s*m_num_labels+l];}
348  private:
349  const EnergyTermType* const m_array;
350  const LabelID m_num_labels;
351  };
352 
354  DataCostFnFromFunction(DataCostFn fn): m_fn(fn){}
355  OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l){return m_fn(s,l);}
356  private:
357  const DataCostFn m_fn;
358  };
359 
361  DataCostFnFromFunctionExtra(DataCostFnExtra fn,void *extraData): m_fn(fn),m_extraData(extraData){}
362  OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l){return m_fn(s,l,m_extraData);}
363  private:
364  const DataCostFnExtra m_fn;
365  void *m_extraData;
366  };
367 
369  SmoothCostFnFromArray(EnergyTermType* theArray, LabelID num_labels)
370  : m_array(theArray), m_num_labels(num_labels){}
371  OLGA_INLINE EnergyTermType compute(SiteID , SiteID , LabelID l1, LabelID l2){return m_array[l1*m_num_labels+l2];}
372  private:
373  const EnergyTermType* const m_array;
374  const LabelID m_num_labels;
375  };
376 
378  SmoothCostFnFromFunction(SmoothCostFn fn)
379  : m_fn(fn){}
380  OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2){return m_fn(s1,s2,l1,l2);}
381  private:
382  const SmoothCostFn m_fn;
383  };
384 
386  SmoothCostFnFromFunctionExtra(SmoothCostFnExtra fn,void *extraData)
387  : m_fn(fn),m_extraData(extraData){}
388  OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2){return m_fn(s1,s2,l1,l2,m_extraData);}
389  private:
390  const SmoothCostFnExtra m_fn;
391  void *m_extraData;
392  };
393 
395  OLGA_INLINE EnergyTermType compute(SiteID, SiteID, LabelID l1, LabelID l2){return l1 != l2 ? (EnergyTermType)1 : (EnergyTermType)0;}
396  };
397 
399  // DataCostFnSparse
400  // This data cost functor maintains a simple sparse structure
401  // to quickly find the cost associated with any (site,label) pair.
404  // cLogSitesPerBucket basically controls the compression ratio
405  // of the sparse structure: 1 => a dense array, num_sites => a single sparse list.
406  // The amount (cLogSitesPerBucket - cLinearSearchSize) determines the maximum
407  // number of binary search steps taken for a cost lookup for specific (site,label).
408  //
409  static const int cLogSitesPerBucket = 9;
410  static const int cSitesPerBucket = (1 << cLogSitesPerBucket);
411  static const size_t cDataCostPtrMask = ~(sizeof(SparseDataCost)-1);
412  static const ptrdiff_t cLinearSearchSize = 64/sizeof(SparseDataCost);
413 
414  struct DataCostBucket {
415  const SparseDataCost* begin;
416  const SparseDataCost* end; // one-past-the-last item in the range
417  const SparseDataCost* predict; // predicts the next cost to be needed
418  };
419 
420  public:
421  DataCostFnSparse(SiteID num_sites, LabelID num_labels);
423  ~DataCostFnSparse();
424 
425  void set(LabelID l, const SparseDataCost* costs, SiteID count);
426  EnergyTermType compute(SiteID s, LabelID l);
427  SiteID queryActiveSitesExpansion(LabelID alpha_label, const LabelID* labeling, SiteID* activeSites);
428 
429  class iterator {
430  public:
431  OLGA_INLINE iterator(): m_ptr(0) { }
432  OLGA_INLINE iterator& operator++() { m_ptr++; return *this; }
433  OLGA_INLINE SiteID site() const { return m_ptr->site; }
434  OLGA_INLINE EnergyTermType cost() const { return m_ptr->cost; }
435  OLGA_INLINE bool operator==(const iterator& b) const { return m_ptr == b.m_ptr; }
436  OLGA_INLINE bool operator!=(const iterator& b) const { return m_ptr != b.m_ptr; }
437  OLGA_INLINE ptrdiff_t operator- (const iterator& b) const { return m_ptr - b.m_ptr; }
438  private:
439  OLGA_INLINE iterator(const SparseDataCost* ptr): m_ptr(ptr) { }
440  const SparseDataCost* m_ptr;
441  friend class DataCostFnSparse;
442  };
443 
444  OLGA_INLINE iterator begin(LabelID label) const { return m_buckets[label*m_buckets_per_label].begin; }
445  OLGA_INLINE iterator end(LabelID label) const { return m_buckets[label*m_buckets_per_label + m_buckets_per_label-1].end; }
446 
447  private:
448  EnergyTermType search(DataCostBucket& b, SiteID s);
449  const SiteID m_num_sites;
450  const LabelID m_num_labels;
451  const int m_buckets_per_label;
452  mutable DataCostBucket* m_buckets;
453  };
454 
455  template <typename DataCostT> SiteID queryActiveSitesExpansion(LabelID alpha_label, SiteID* activeSites);
456  template <typename DataCostT> void setupDataCostsExpansion(SiteID size,LabelID alpha_label,EnergyT *e,SiteID *activeSites);
457  template <typename DataCostT> void setupDataCostsSwap(SiteID size,LabelID alpha_label,LabelID beta_label,EnergyT *e,SiteID *activeSites);
458  template <typename SmoothCostT> void setupSmoothCostsExpansion(SiteID size,LabelID alpha_label,EnergyT *e,SiteID *activeSites);
459  template <typename SmoothCostT> void setupSmoothCostsSwap(SiteID size,LabelID alpha_label,LabelID beta_label,EnergyT *e,SiteID *activeSites);
460  template <typename DataCostT> void applyNewLabeling(EnergyT *e,SiteID *activeSites,SiteID size,LabelID alpha_label);
461  template <typename DataCostT> void updateLabelingDataCosts();
462  template <typename UserFunctor> void specializeDataCostFunctor(const UserFunctor f);
463  template <typename UserFunctor> void specializeSmoothCostFunctor(const UserFunctor f);
464 
465  EnergyType setupLabelCostsExpansion(SiteID size,LabelID alpha_label,EnergyT *e,SiteID *activeSites);
466  void updateLabelingInfo(bool updateCounts=true,bool updateActive=true,bool updateCosts=true);
467 
468  // Check for overflow and submodularity issues when setting up binary graph cut
469  void addterm1_checked(EnergyT *e,VarID i,EnergyTermType e0,EnergyTermType e1);
470  void addterm1_checked(EnergyT *e,VarID i,EnergyTermType e0,EnergyTermType e1,EnergyTermType w);
471  void addterm2_checked(EnergyT *e,VarID i,VarID j,EnergyTermType e00,EnergyTermType e01,EnergyTermType e10,EnergyTermType e11,EnergyTermType w);
472 
473  // Returns Smooth Energy of current labeling
474  template <typename SmoothCostT> EnergyType giveSmoothEnergyInternal();
475  template <typename Functor> static void deleteFunctor(void* f) { delete reinterpret_cast<Functor*>(f); }
476 
477  static void handleError(const char *message);
478  static void checkInterrupt();
479 
480 private:
481  // Peforms one iteration (one pass over all pairs of labels) of expansion/swap algorithm
482  EnergyType oneExpansionIteration();
483  EnergyType oneSwapIteration();
484  void printStatus1(const char* extraMsg=0);
485  void printStatus1(int cycle, bool isSwap, gcoclock_t ticks0);
486  void printStatus2(int alpha, int beta, int numVars, gcoclock_t ticks0);
487 
488  void permuteLabelTable();
489 
490  template <typename DataCostT> bool solveSpecialCases(EnergyType& energy);
491  template <typename DataCostT> EnergyType solveGreedy();
492 
494  // GreedyIter
495  // Lets solveGreedy efficiently traverse the datacosts when
496  // searching for the next greedy move.
498  template <typename DataCostT>
499  class GreedyIter {
500  public:
501  GreedyIter(DataCostT& dc, SiteID numSites)
502  : m_dc(dc), m_site(0), m_numSites(numSites), m_label(0), m_lbegin(0), m_lend(0)
503  { }
504 
505  OLGA_INLINE void start(const LabelID* labels, LabelID labelCount=1)
506  {
507  m_site = labelCount ? 0 : m_numSites;
508  m_label = m_lbegin = labels;
509  m_lend = labels + labelCount;
510  }
511  OLGA_INLINE SiteID site() const { return m_site; }
512  OLGA_INLINE SiteID label() const { return *m_label; }
513  OLGA_INLINE bool done() const { return m_site == m_numSites; }
514  OLGA_INLINE GreedyIter& operator++()
515  {
516  // The inner loop is over labels, not sites, to improve memory locality.
517  // When dc() is pulling datacosts from an array (the typical format), this can
518  // improve performance by a factor of 2x, often more like 4x.
519  if (++m_label >= m_lend) {
520  m_label = m_lbegin;
521  ++m_site;
522  }
523  return *this;
524  }
525  OLGA_INLINE EnergyTermType compute() const { return m_dc.compute(m_site,*m_label); }
526  OLGA_INLINE SiteID feasibleSites() const { return m_numSites; }
527 
528  private:
529  SiteID m_site;
530  DataCostT& m_dc;
531  const SiteID m_numSites;
532  const LabelID* m_label;
533  const LabelID* m_lbegin;
534  const LabelID* m_lend;
535  };
536 };
537 
538 
540 // Use this derived class for grid graphs
542 
544 {
545 public:
546  GCoptimizationGridGraph(SiteID width,SiteID height,LabelID num_labels);
547  virtual ~GCoptimizationGridGraph();
548 
549  void setSmoothCostVH(EnergyTermType *smoothArray, EnergyTermType *vCosts, EnergyTermType *hCosts);
550 
551 protected:
552  virtual void giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights);
553  virtual void finalizeNeighbors();
554  EnergyTermType m_unityWeights[4];
555  int m_weightedGraph; // true if spatially varying w_pq's are present. False otherwise.
556 
557 private:
558  SiteID m_width;
559  SiteID m_height;
560  SiteID *m_neighbors; // holds neighbor indexes
561  EnergyTermType *m_neighborsWeights; // holds neighbor weights
562 
563  void setupNeighbData(SiteID startY,SiteID endY,SiteID startX,SiteID endX,SiteID maxInd,SiteID *indexes);
564  void computeNeighborWeights(EnergyTermType *vCosts,EnergyTermType *hCosts);
565 };
566 
568 
570 {
571 public:
572  // This is the constructor for non-grid graphs. Neighborhood structure must be specified by
573  // setNeighbors() function
574  GCoptimizationGeneralGraph(SiteID num_sites,LabelID num_labels);
575  virtual ~GCoptimizationGeneralGraph();
576 
577  // Makes site1 and site2 neighbors of each other. Can be called only 1 time for each
578  // unordered pair of sites. Parameter weight can be used to set spacially varying terms
579  // If the desired penalty for neighboring sites site1 and site2 is
580  // V(label1,label2) = weight*SmoothnessPenalty(label1,label2), then
581  // member function setLabel should be called as: setLabel(site1,site2,weight)
582  void setNeighbors(SiteID site1, SiteID site2, EnergyTermType weight=1);
583 
584  // passes pointers to arrays storing neighbor information
585  // numNeighbors[i] is the number of neighbors for site i
586  // neighborsIndexes[i] is a pointer to the array storing the sites which are neighbors to site i
587  // neighborWeights[i] is a pointer to array storing the weights between site i and its neighbors
588  // in the same order as neighborIndexes[i] stores the indexes
589  void setAllNeighbors(SiteID *numNeighbors,SiteID **neighborsIndexes,EnergyTermType **neighborsWeights);
590 
591 protected:
592  virtual void giveNeighborInfo(SiteID site, SiteID *numSites, SiteID **neighbors, EnergyTermType **weights);
593  virtual void finalizeNeighbors();
594 
595 private:
596 
597  typedef struct NeighborStruct{
598  SiteID to_node;
599  EnergyTermType weight;
600  } Neighbor;
601 
602  LinkedBlockList *m_neighbors;
603  bool m_needToFinishSettingNeighbors;
604  SiteID **m_neighborsIndexes;
605  EnergyTermType **m_neighborsWeights;
606  bool m_needTodeleteNeighbors;
607 };
608 
609 
611 // Methods
613 
614 
616 {
617  return m_num_sites;
618 }
619 
621 {
622  return m_num_labels;
623 }
624 
626 {
627  assert(label >= 0 && label < m_num_labels && site >= 0 && site < m_num_sites);
628  m_labeling[site] = label;
629  m_labelingInfoDirty = true;
630 }
631 
633 {
634  assert(site >= 0 && site < m_num_sites);
635  return m_labeling[site];
636 }
637 
638 // diem: compiler warnings
639 #ifdef _MSC_VER
640 #pragma warning(pop) // no warnings from includes
641 #elif __GNUC__
642 #pragma GCC diagnostic pop
643 #endif
644 
645 #endif
LabelCostIter * next
Definition: GCoptimization.h:297
Definition: GCoptimization.h:228
int m_stepsThisCycle
Definition: GCoptimization.h:306
LabelCost * next
Definition: GCoptimization.h:290
int LabelID
Definition: GCoptimization.h:184
int EnergyTermType
Definition: GCoptimization.h:180
SmoothCostFnFromFunctionExtra(SmoothCostFnExtra fn, void *extraData)
Definition: GCoptimization.h:386
~LabelCost()
Definition: GCoptimization.h:286
VarID aux
Definition: GCoptimization.h:289
OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l)
Definition: GCoptimization.h:355
LabelID * m_labeling
Definition: GCoptimization.h:302
EnergyTermType * m_smoothcostIndividual
Definition: GCoptimization.h:310
const char * message
Definition: GCoptimization.h:129
LabelID whatLabel(SiteID site)
Definition: GCoptimization.h:632
OLGA_INLINE bool operator!=(const iterator &b) const
Definition: GCoptimization.h:436
int m_weightedGraph
Definition: GCoptimization.h:555
LabelCost * node
Definition: GCoptimization.h:296
Definition: GCoptimization.h:295
OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2)
Definition: GCoptimization.h:388
VarID SiteID
Definition: GCoptimization.h:185
Definition: GCoptimization.h:285
EnergyT::Var VarID
Definition: GCoptimization.h:183
OLGA_INLINE EnergyTermType compute(SiteID s1, SiteID s2, LabelID l1, LabelID l2)
Definition: GCoptimization.h:380
DataCostFnFromFunction(DataCostFn fn)
Definition: GCoptimization.h:354
OLGA_INLINE iterator end(LabelID label) const
Definition: GCoptimization.h:445
Definition: GCoptimization.h:168
SiteID m_num_sites
Definition: GCoptimization.h:301
static void deleteFunctor(void *f)
Definition: GCoptimization.h:475
SiteID * m_lookupSiteVar
Definition: GCoptimization.h:303
Definition: GCoptimization.h:368
OLGA_INLINE iterator()
Definition: GCoptimization.h:431
bool active
Definition: GCoptimization.h:288
void Report()
Definition: GCoptimization.cpp:95
OLGA_INLINE bool operator==(const iterator &b) const
Definition: GCoptimization.h:435
Definition: GCoptimization.h:394
EnergyTermType * m_labelingDataCosts
Definition: GCoptimization.h:311
Definition: GCoptimization.h:377
void setLabel(SiteID site, LabelID label)
Definition: GCoptimization.h:625
LabelID * m_labelTable
Definition: GCoptimization.h:305
LabelID numLabels
Definition: GCoptimization.h:291
DataCostFnFromFunctionExtra(DataCostFnExtra fn, void *extraData)
Definition: GCoptimization.h:361
OLGA_INLINE SiteID site() const
Definition: GCoptimization.h:433
OLGA_INLINE EnergyTermType compute(SiteID, SiteID, LabelID l1, LabelID l2)
Definition: GCoptimization.h:395
void * m_smoothcostFn
Definition: GCoptimization.h:321
OLGA_INLINE iterator & operator++()
Definition: GCoptimization.h:432
Definition: GCoptimization.h:241
OLGA_INLINE EnergyTermType compute(SiteID, SiteID, LabelID l1, LabelID l2)
Definition: GCoptimization.h:371
SiteID m_numNeighborsTotal
Definition: GCoptimization.h:325
Definition: GCoptimization.h:353
OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l)
Definition: GCoptimization.h:362
gcoclock_t gcoclock()
Definition: GCoptimization.cpp:54
EnergyTermType cost
Definition: GCoptimization.h:287
#define OLGA_INLINE
Definition: GCoptimization.h:146
SmoothCostFnFromArray(EnergyTermType *theArray, LabelID num_labels)
Definition: GCoptimization.h:369
SiteID * m_numNeighbors
Definition: GCoptimization.h:324
EnergyType m_beforeExpansionEnergy
Definition: GCoptimization.h:322
Definition: GCoptimization.h:403
bool m_labelingInfoDirty
Definition: GCoptimization.h:317
Definition: GCoptimization.h:569
GraphT::node_id Var
Definition: energy.h:83
int m_labelcostCount
Definition: GCoptimization.h:316
level
Definition: DependencyCollector.py:25
Energy< EnergyTermType, EnergyTermType, EnergyType > EnergyT
Definition: GCoptimization.h:182
Definition: GCoptimization.h:429
long long EnergyType
Definition: GCoptimization.h:178
OLGA_INLINE EnergyTermType cost() const
Definition: GCoptimization.h:434
SiteID * m_activeLabelCounts
Definition: GCoptimization.h:313
int m_verbosity
Definition: GCoptimization.h:318
int m_stepsThisCycleTotal
Definition: GCoptimization.h:307
LabelCost * m_labelcostsAll
Definition: GCoptimization.h:314
LabelID m_num_labels
Definition: GCoptimization.h:300
Definition: GCoptimization.h:543
LabelID * labels
Definition: GCoptimization.h:292
gcoclock_t GCO_CLOCKS_PER_SEC
Definition: GCoptimization.h:141
Definition: GCoptimization.h:127
SiteID numSites() const
Definition: GCoptimization.h:615
EnergyTermType * m_datacostIndividual
Definition: GCoptimization.h:309
Definition: energy.h:79
int m_random_label_order
Definition: GCoptimization.h:308
DataCostFnFromArray(EnergyTermType *theArray, LabelID num_labels)
Definition: GCoptimization.h:345
LabelCostIter ** m_labelcostsByLabel
Definition: GCoptimization.h:315
Definition: GCoptimization.h:344
GCException(const char *m)
Definition: GCoptimization.h:130
Definition: GCoptimization.h:360
SiteID site
Definition: GCoptimization.h:229
OLGA_INLINE iterator begin(LabelID label) const
Definition: GCoptimization.h:444
OLGA_INLINE EnergyTermType compute(SiteID s, LabelID l)
Definition: GCoptimization.h:347
void * m_datacostFn
Definition: GCoptimization.h:320
EnergyTermType cost
Definition: GCoptimization.h:230
void setVerbosity(int level)
Definition: GCoptimization.h:282
Definition: GCoptimization.h:223
Definition: LinkedBlockList.h:21
LabelID numLabels() const
Definition: GCoptimization.h:620
SiteID * m_labelCounts
Definition: GCoptimization.h:312
Definition: GCoptimization.h:385
SmoothCostFnFromFunction(SmoothCostFn fn)
Definition: GCoptimization.h:378
clock_t gcoclock_t
Definition: GCoptimization.h:138