DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
project.h
Go to the documentation of this file.
1 
2 /* Software SPAMS v2.1 - Copyright 2009-2011 Julien Mairal
3  *
4  * This file is part of SPAMS.
5  *
6  * SPAMS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * SPAMS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with SPAMS. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef PROJECT_H
21 #define PROJECT_H
22 
23 #include <linalg.h>
24 #include <limits>
25 
26 #define EPSILON_MAXFLOW 1e-10
27 
28 namespace spams
29 {
30 
31 //#define VERBB
32 //#define VERB2
33 
34 
39 bool global_heuristic = true;
40 bool gap_heuristic = true;
41 bool cap_heuristic = true;
42 bool price_heuristic = true;
44 
45 //typedef std::list<int> list_int;
46 //typedef std::list<int>::const_iterator const_iterator_int;
47 #include <list.h>
48 
50 
51 template <typename T>
52 bool compare_abs (T first, T second) {
53  return abs<T>(first) >= abs<T>(second);
54 }
55 template <typename T>
56 T inline project_tree_l1(T* variables, const int n, const T lambda);
57 
58 template <typename T>
59 T inline project_tree_l1(T* X, const int n, const T lambda) {
60  if (lambda==0) return INFINITY;
61  T* prU = X;
62  T sum = 0;
63  int sum_card = n;
64  for (int i = 0; i<sum_card; ++i) {
65  if (X[i]) {
66  sum += X[i];
67  } else {
68  swap(X[i],X[--sum_card]);
69  --i;
70  }
71  }
72  if (sum < lambda) {
73  memset(X,0,sum_card*sizeof(T));
74  return 0;
75  }
76  int sizeU = sum_card;
77  sum_card = 0;
78  sum=0;
79 
80  while (sizeU > 0) {
81  // put the pivot in prU[0]
82  swap(prU[0],prU[sizeU/2]);
83  int sizeG=1;
84  T sumG=prU[0];
85 
86  for (int i = 1; i<sizeU; ++i) {
87  if (prU[i] >= prU[0]) {
88  sumG += prU[i];
89  swap(prU[sizeG++],prU[i]);
90  }
91  }
92 
93  T new_sum=sum+sumG;
94  int new_card=sum_card+sizeG;
95  if (new_sum - prU[0]*new_card <= lambda) {
96  sum_card = new_card;
97  sum = new_sum;
98  prU +=sizeG;
99  sizeU -= sizeG;
100  } else {
101  ++prU;
102  sizeU = sizeG-1;
103  }
104  }
105  T thrs = MAX(0,(sum-lambda)/sum_card);
106  for (int i = 0; i<n; ++i)
107  X[i] = MIN(X[i],thrs);
108  return thrs;
109 };
110 
111 template <typename T> class Tree_Seq {
112 
113  public:
114  Tree_Seq();
115  ~Tree_Seq();
116 
117  void inline create_tree(const int N_variables, int* own_variables,
118  int* N_own_variables, T* lambda, mwSize* groups_ir, mwSize* groups_jc,
119  const int N_groups, const int root_node = 0);
120 
121  int inline perform_order(const int current_node, const int pointer);
122  int inline perform_dfs(const int current_node, const int pointer);
123 
124  void inline proj(Vector<T>& input, const bool l1 = false,
125  const T fact = 1.0);
126  void inline proj_zero(Vector<T>& input, const T fact = 1.0);
127 
128  void inline proj_weighted_linf(Vector<T>& input, const Vector<T>& weights, const T fact = 1.0);
129 
130  T inline val_norm(const T* pr_alpha, const int current_node, const bool l1 = false);
131  T inline val_norm2(const T* pr_alpha, const int current_node, T& tmp, const bool l1 = false);
132  T inline val_zero(const T* pr_alpha, const int current_node);
133  T inline val_zero2(const T* pr_alpha, const int current_node, bool& tmp);
134  T inline dual_norm_inf(const Vector<T>& input);
135  void inline sub_grad(const Vector<T>& input, Vector<T>& output, const bool linf);
136 
137  private:
141  T* _thrs;
143  T* _work;
148  int* _order;
152 
153 };
154 
155 template <typename T>
157  _lambda=NULL;
158  _thrs=NULL;
159  _work=NULL;
160  _variables=NULL;
161  _N_groups=0;
162  _N_variables=0;
163  _size_variables=NULL;
164  _pr_variables=NULL;
165  _size_own_variables=NULL;
166  _order=NULL;
167  _order_dfs=NULL;
168  _groups_ir=NULL;
169  _groups_jc=NULL;
170 };
171 
172 template <typename T>
174  delete[](_thrs);
175  delete[](_work);
176  delete[](_variables);
177  delete[](_size_variables);
178  delete[](_pr_variables);
179  delete[](_order);
180  delete[](_order_dfs);
181 };
182 
183 template <typename T>
184 void inline Tree_Seq<T>::create_tree(const int N_variables, int* own_variables,
185  int* N_own_variables, T* lambda, mwSize* groups_ir,mwSize* groups_jc,
186  const int N_groups, const int root_node) {
187  _N_groups=N_groups;
188  _N_variables=N_variables;
189  _lambda=lambda;
190  _thrs=new T[N_groups];
191  _variables=new T[N_variables];
192  _size_variables=new int[N_groups];
193  _pr_variables=new int[N_groups];
194  _size_own_variables=N_own_variables;
195  _pr_own_variables=own_variables;
196  _order=new int[N_groups];
197  _order_dfs=new int[N_groups];
198  _groups_ir=groups_ir;
199  _groups_jc=groups_jc;
200  this->perform_order(root_node,0);
201  this->perform_dfs(root_node,0);
202  _work = new T[MAX(N_groups,N_variables)];
203 };
204 
205 template <typename T>
206 int inline Tree_Seq<T>::perform_order(const int current_node, const int pointer) {
207  int cur_pointer=pointer;
208  _size_variables[current_node]=_size_own_variables[current_node];
209  _pr_variables[current_node]=_pr_own_variables[current_node];
210  for (int i = _groups_jc[current_node]; i<_groups_jc[current_node+1]; ++i) {
211  cur_pointer=this->perform_order(_groups_ir[i],cur_pointer);
212  _size_variables[current_node]+=_size_variables[_groups_ir[i]];
213  _pr_variables[current_node]= MIN(_pr_variables[current_node],_pr_variables[_groups_ir[i]]);
214  }
215  _order[cur_pointer]=current_node;
216  return cur_pointer+1;
217 };
218 
219 template <typename T>
220 int inline Tree_Seq<T>::perform_dfs(const int current_node, const int pointer) {
221  int cur_pointer=pointer;
222  _order_dfs[cur_pointer++]=current_node;
223  for (int i = _groups_jc[current_node]; i<_groups_jc[current_node+1]; ++i) {
224  cur_pointer=this->perform_dfs(_groups_ir[i],cur_pointer);
225  }
226  return cur_pointer;
227 };
228 
229 // could be faster
230 template <typename T>
231 T inline Tree_Seq<T>::val_norm(const T* pr_alpha, const int current_node, const bool l1) {
232  T tmp=0;
233  return this->val_norm2(pr_alpha,current_node,tmp,l1);
234 };
235 
236 // fast version
237 template <typename T>
238 T inline Tree_Seq<T>::val_norm2(const T* pr_alpha, const int current_node, T& tmp, const bool l1) {
239  T sum=0;
240  for (int i = _groups_jc[current_node]; i<_groups_jc[current_node+1]; ++i) {
241  T tmp2=0;
242  sum+=this->val_norm2(pr_alpha,_groups_ir[i],tmp2,l1);
243  tmp= l1 ? MAX(tmp,tmp2) : tmp+tmp2;
244  }
245  if (l1) {
246  for (int i = 0; i<_size_own_variables[current_node]; ++i)
247  tmp=MAX(abs<T>(pr_alpha[i+_pr_variables[current_node]]),tmp);
248  sum+=_lambda[current_node]*tmp;
249  } else {
250  tmp += cblas_dot<T>(_size_own_variables[current_node],const_cast<T*>(pr_alpha+_pr_variables[current_node]),1,const_cast<T*>(pr_alpha+_pr_variables[current_node]),1);
251  //tmp += cblas_dot<T>(_size_own_variables[current_node],pr_alpha+_pr_variables[current_node],1,pr_alpha+_pr_variables[current_node],1);
252  sum+=_lambda[current_node]*sqrt(tmp);
253  }
254  return sum;
255 };
256 
257 template <typename T>
258 T inline Tree_Seq<T>::val_zero2(const T* pr_alpha, const int current_node, bool& tmp) {
259  T sum=0;
260  for (int i = _groups_jc[current_node]; i<_groups_jc[current_node+1]; ++i) {
261  bool tmp2=false;
262  sum+=this->val_zero2(pr_alpha,_groups_ir[i],tmp2);
263  tmp = tmp || tmp2;
264  }
265  for (int i = 0; i<_size_own_variables[current_node]; ++i)
266  tmp= (tmp || pr_alpha[i+_pr_variables[current_node]] != 0);
267  if (tmp)
268  sum+=_lambda[current_node];
269  return sum;
270 };
271 
272 
273 template <typename T>
274 T inline Tree_Seq<T>::val_zero(const T* pr_alpha, const int current_node) {
275  bool tmp = false;
276  return this->val_zero2(pr_alpha,current_node,tmp);
277 };
278 
279 template <typename T>
280 void inline Tree_Seq<T>::sub_grad(const Vector<T>& input, Vector<T>& output, const bool linf) {
281  output.setZeros();
282  if (linf) {
283  for (int i = 0; i<_N_groups; ++i) {
284  const T* pr = input.rawX()+_pr_variables[i];
285  int imax=cblas_iamax<T>(_size_variables[i],const_cast<T*>(pr),1);
286  // int imax=cblas_iamax<T>(_size_variables[i],pr,1);
287  T max=pr[imax];
288  int num_max=0;
289  for (int j = 0; j<_size_variables[i];++j) {
290  if (abs<T>(max-abs<T>(pr[j])) < 1e-10) ++num_max;
291  }
292  T add=T(1.0)/num_max;
293  for (int j = 0; j<_size_variables[i];++j) {
294  if (abs<T>(max-abs<T>(pr[j])) < 1e-10 && input[_pr_variables[i]+j]) {
295  output[_pr_variables[i]+j]+= input[_pr_variables[i]+j] > 0 ? add : -add;
296  }
297  }
298  }
299  } else {
300  for (int i = 0; i<_N_groups; ++i) {
301  T nrm=cblas_nrm2<T>(_size_variables[i],input.rawX()+_pr_variables[i],1);
302  if (nrm > 0) {
303  cblas_axpy<T>(_size_variables[i],T(1.0)/nrm,input.rawX()+_pr_variables[i],1,output.rawX()+_pr_variables[i],1);
304 // } else {
305 // T num=T(1.0)/sqrt(static_cast<T>(_size_variables[i]));
306 // for (int j = 0; j<_size_variables[i]; ++j) {
307 // output[_pr_variables[i]+j]+=num;
308 // }
309  }
310  }
311  }
312 };
313 
314 template <typename T>
315 void inline Tree_Seq<T>::proj_weighted_linf(Vector<T>& input, const Vector<T>& weights,
316  const T fact) {
317  Vector<T> weig;
318  weig.copy(weights);
319  weig.inv();
320  cblas_copy<T>(input.n(),input.rawX(),1,_variables,1);
321  Vector<T> tmp, tmpw;
322  for (int i = 0; i<_N_groups; ++i) {
323  const int node=_order[i];
324  Vector<T> out;
326  tmpw.setData(weig.rawX()+_pr_variables[node],_size_variables[node]);
327  tmp.l1project_weighted(out,tmpw,fact,true);
328  cblas_copy<T>(out.n(),out.rawX(),1,_variables+_pr_variables[node],1);
329  tmp.copy(out);
330  }
331  cblas_copy<T>(input.n(),_variables,1,input.rawX(),1);
332 };
333 
334 template <typename T>
335 void inline Tree_Seq<T>::proj(Vector<T>& input, const bool l1,
336  const T fact) {
337  if (l1) {
338  vAbs<T>(input.n(),input.rawX(),_variables);
339  for (int i = 0; i<_N_groups; ++i) {
340  const int node=_order[i];
342  _lambda[node]*fact);
343  }
344  cblas_copy<T>(input.n(),input.rawX(),1,_variables,1);
345  for (int i = 0; i<_N_groups; ++i) {
346  const int node=_order_dfs[i];
347  if (_thrs[node] == 0) {
348  memset(_variables+_pr_own_variables[node],0,_size_own_variables[node]*sizeof(T));
349  for (int j = _groups_jc[node]; j<_groups_jc[node+1]; ++j) {
350  _thrs[_groups_ir[j]]=0;
351  }
352  } else {
353  for (int j = 0; j<_size_own_variables[node]; ++j) {
354  T tmp = _variables[_pr_own_variables[node]+j];
355  _variables[_pr_own_variables[node]+j] = tmp > _thrs[node] ? _thrs[node] :
356  tmp < -_thrs[node] ? -_thrs[node] : tmp;
357  }
358  for (int j = _groups_jc[node]; j<_groups_jc[node+1]; ++j) {
359  _thrs[_groups_ir[j]]= MIN(_thrs[_groups_ir[j]],_thrs[node]);
360  }
361  }
362  }
363  } else {
364  cblas_copy<T>(input.n(),input.rawX(),1,_variables,1);
365  for (int i = 0; i<_N_groups; ++i) {
366  const int node=_order[i];
367  _work[node]=0;
368  for (int j = 0; j<_size_own_variables[node]; ++j)
370  for (int j = _groups_jc[node]; j<_groups_jc[node+1];++j)
371  _work[node] += _work[_groups_ir[j]];
372  _thrs[node] = MAX(0,1-fact*_lambda[node]/sqrt(_work[node]));
373  _work[node]*= _thrs[node]*_thrs[node];
374  }
375  for (int i = 0; i<_N_groups; ++i) {
376  const int node=_order_dfs[i];
377  if (_thrs[node] == 0) {
378  memset(_variables+_pr_own_variables[node],0,_size_own_variables[node]*sizeof(T));
379  for (int j = _groups_jc[node]; j<_groups_jc[node+1]; ++j) {
380  _thrs[_groups_ir[j]]=0;
381  }
382  } else {
383  for (int j = 0; j<_size_own_variables[node]; ++j)
384  _variables[_pr_own_variables[node]+j] *= _thrs[node];
385  for (int j = _groups_jc[node]; j<_groups_jc[node+1]; ++j) {
386  _thrs[_groups_ir[j]] *= _thrs[node];
387  }
388  }
389  }
390  }
391  cblas_copy<T>(input.n(),_variables,1,input.rawX(),1);
392 };
393 
394 template <typename T>
395 void inline Tree_Seq<T>::proj_zero(Vector<T>& input, const T fact) {
396  cblas_copy<T>(input.n(),input.rawX(),1,_variables,1);
397  for (int i = 0; i<_N_groups; ++i) {
398  const int node=_order[i];
399  _work[node]=0;
400  for (int j = 0; j<_size_own_variables[node]; ++j)
402  _work[node] *= -0.5;
403  _work[node] += fact*_lambda[node];
404  for (int j = _groups_jc[node]; j<_groups_jc[node+1];++j)
405  _work[node] += _work[_groups_ir[j]];
406  if (_work[node] > 0) _work[node]=0;
407  }
408  for (int i = 0; i<_N_groups; ++i) {
409  const int node=_order_dfs[i];
410  if (_work[node] == 0) {
411  memset(_variables+_pr_own_variables[node],0,_size_own_variables[node]*sizeof(T));
412  for (int j = _groups_jc[node]; j<_groups_jc[node+1]; ++j) {
413  _work[_groups_ir[j]]=0;
414  }
415  }
416  }
417  cblas_copy<T>(input.n(),_variables,1,input.rawX(),1);
418 }
419 
420 template <typename T>
421 T inline Tree_Seq<T>::dual_norm_inf(const Vector<T>& input) {
422  tglobal1.reset();
423  tglobal2.reset();
424  tglobal3.reset();
425  for (int i = 0; i<_N_groups; ++i) {
426  _thrs[_order[i]]=INFINITY;
427  }
428  T tau=0;
429  T sum_variables=INFINITY;
430  T total=input.asum();
431  while (_thrs[0] > EPSILON) {
432  T old_thrs=_thrs[0];
433  vAbs<T>(_N_variables,input.rawX(),_variables);
434  list_int nodes;
435  nodes.push_front(0);
436  list_int ordered_nodes;
437  T sum_weights=0;
438  sum_variables=total;
439  while (!nodes.empty()) {
440  const int node=nodes.front();
441  nodes.pop_front();
442  sum_weights+=_lambda[node];
443  for (int j = _groups_jc[node]; j<_groups_jc[node+1]; ++j)
444  if (_thrs[_groups_ir[j]] > EPSILON) {
445  nodes.push_front(_groups_ir[j]);
446  } else {
447  sum_variables -= cblas_asum<T>(_size_variables[_groups_ir[j]],_variables+_pr_variables[_groups_ir[j]],1);
448  memset(_variables+_pr_variables[_groups_ir[j]],0,_size_variables[_groups_ir[j]]*sizeof(T));
449  }
450  ordered_nodes.push_front(node);
451  }
452  tau=sum_variables/sum_weights;
453  for (const_iterator_int it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it) {
454  const int node=*it;
455  _thrs[node] = project_tree_l1(_variables+_pr_variables[node],_size_variables[node],_lambda[node]*tau);
456  }
457  if (_thrs[0] >= old_thrs) break;
458  }
459  return tau;
460 };
461 
462 
463 template <typename T> class MaxFlow {
464 
465  public:
466  MaxFlow(const int N, const int* num_edges, const int s, const int t);
467  ~MaxFlow();
468 
469  void inline add_edge(const int u, const int v, const T cu, const T cv);
470 
471  void inline discharge(const list_int& component, const int u,const int max_label);
472 
473  void inline global_relabelling();
474 
475  void inline perform_maxflow();
476 
477  void inline print_excess();
478  void inline print_labels();
479 
480  void inline deactivate();
481  void inline deactivate(const list_int& component);
482 
483  T inline getMaxFlow() const { return _excess[_t]; };
484 
485  void inline extractConnexComponents(std::list< list_int* >& connex_components);
486  T inline project(const list_int& component,
487  const T* variables_in,T* variables_out,T* work,
488  const int Ng);
489  T inline project_weighted(const list_int& component,
490  const T* variables_in,T* variables_out,T* work, const T* weights,
491  const int Ng);
492  T inline project_box(const list_int& component, const T* variables_in,T*
493  variables_out,T* work, bool& fusion, const int Ng);
494 
495  T inline flow_component(const list_int& component, const int Ng);
496  bool inline splitComponent(const list_int& component,
497  std::list< list_int* >& connex_components, const int Ng, bool* positive,const bool addpos = true);
498  void inline reset_component(const list_int& component);
499  void inline perform_maxflow_component(const list_int& component);
500  void inline component_relabelling(const list_int& component,
501  const int max_label, const bool force);
502  void inline gap_relabelling(const list_int& component, const int gap, const int max_label);
503  void inline component_gap(const list_int& component);
504  void inline update_capacities(const list_int& component,T* work);
505  void inline set_capacities_variables(const T* cap,const int Nv, const int Ng);
506  void inline set_capacities_groups(const list_int& component,
507  const Vector<T>& weights,const T lambda, const int Ng);
508  void inline update_capacities_aux(const int node,T* work);
509  void inline restore_capacities(const list_int& component);
510  T inline compute_thrs_project_l1(T* X, const int n, const T lambda);
511 
512  bool inline check_flow();
513  void inline restore_capacities();
514  void inline restore_flow();
515  void inline reset_flow();
516  void inline scale_flow(const T scal);
517  void inline save_capacities();
518  void inline save_flow();
519  void inline set_weights(const T lambda);
520  void inline set_weights(const T* weights, const T lambda);
521  void inline print_graph();
522  inline void init_split_variables(SpMatrix<T>& splitted_w, const int Ng, const int Nv);
523  inline void init_split_variables_aux(const int node, int& current_counter, Vector<int>& counter_node, list_int** splitted_w,
524  const int Ng, const int Nv);
525  void inline print_component(const list_int& component);
526  void inline print_component2(const list_int& component);
527  void inline print_sink();
528  void inline print_graph_aux(const int node);
529  T inline norm(const T* variables, T* work, const T* weights, const int Ng, const bool linf = true);
530  inline int nzmax() const { return _nzmax; };
531  void inline sub_gradient(const Vector<T>& input, Vector<T>& output, const Vector<T>& weights, const int Ng);
532  void inline sub_gradient_aux(const Vector<T>& input, Vector<T>& output, const Vector<T>& weights,
533  const int node, list_int& list, const int Ng);
534 
535  private:
536  int _N;
537  int _s;
538  int _t;
539 
540  int* _labels;
543  bool* _seen;
544  bool* _active;
545 
549  int* _pr_node;
550  int _nzmax;
551 
552  int* _children;
556  T* _flow;
558 
562 };
563 
564 template <typename T>
565 MaxFlow<T>::MaxFlow(const int N, const int* num_edges, const int s, const int t) {
566  _N=N;
567  _s=s;
568  _t=t;
569 
570  _labels=new int[N];
571  memset(_labels,0,N*sizeof(int));
572  _excess=new T[N];
573  memset(_excess,0,N*sizeof(T));
574  _excess[_s]=INFINITY;
575  _seen=new bool[N];
576  _active=new bool[N];
577  _num_edges=new int[N];
578  _current_edges=new int[N];
579  memset(_num_edges,0,N*sizeof(int));
580  memset(_current_edges,0,N*sizeof(int));
581  _max_num_edges=new int[N];
582  for (int i = 0; i<N; ++i) _max_num_edges[i]=num_edges[i];
583  _pr_node=new int[N+1];
584  _pr_node[0]=0;
585  for (int i = 1; i<=N; ++i) _pr_node[i]=_pr_node[i-1]+_max_num_edges[i-1];
586  _nzmax=_pr_node[N];
587  _children= new int[_nzmax];
588  _reverse_address= new int[_nzmax];
589  _capacity= new T[_nzmax];
590  _copycapacity= new T[_nzmax];
591  _flow= new T[_nzmax];
592  memset(_flow,0,_nzmax*sizeof(T));
593  _current_max_label=0;
594  _active_nodes = new list_int*[N+1];
595  _all_nodes= new int[N+1];
596  for (int i = 0; i<=N; ++i) _active_nodes[i]=new list_int();
597 };
598 
599 template <typename T>
601  delete[](_labels);
602  delete[](_excess);
603  delete[](_seen);
604  delete[](_active);
605  delete[](_num_edges);
606  delete[](_current_edges);
607  delete[](_max_num_edges);
608  delete[](_children);
609  delete[](_reverse_address);
610  delete[](_capacity);
611  delete[](_copycapacity);
612  delete[](_flow);
613  for (int i = 0; i<=_N; ++i) delete(_active_nodes[i]);
614  delete[](_active_nodes);
615  delete[](_all_nodes);
616  delete[](_pr_node);
617 };
618 
619 template <typename T>
620 void inline MaxFlow<T>::add_edge(const int u, const int v, const T Cu, const T Cv) {
621  if (u != v) {
622  const int pu=_pr_node[u];
623  const int pv=_pr_node[v];
624  const int nu=_num_edges[u]+pu;
625  const int nv=_num_edges[v]+pv;
626  _children[nu]=v;
627  _children[nv]=u;
628  _capacity[nu]=Cu;
629  _capacity[nv]=Cv;
630  _reverse_address[nu]=nv;
631  _reverse_address[nv]=nu;
632  _num_edges[u]++;
633  _num_edges[v]++;
634  }
635 };
636 
637 template <typename T>
638 void inline MaxFlow<T>::discharge(const list_int& component, const int u, const int max_label) {
639 #ifdef VERBB
640  cerr << "Discharge " << u << endl;
641 #endif
642  const T* capacity=_capacity+_pr_node[u];
643  T* flow=_flow+_pr_node[u];
644  const int* children=_children+_pr_node[u];
645  const int* reverse=_reverse_address+_pr_node[u];
646  int pr=0;
647  const int curr=_current_edges[u];
648  const int nn=_num_edges[u];
649 
650  int m = max_label;
651  while (_excess[u] > EPSILON_MAXFLOW && pr < nn) {
652  const int num_c=(pr+curr) % nn;
653  const int v=children[num_c];
654  if (capacity[num_c] > flow[num_c]) {
655  if (_labels[u] > _labels[v]) {
656  // push
657  const T delta=MIN(_excess[u],capacity[num_c]-flow[num_c]);
658  _excess[u]-=delta;
659  flow[num_c]+=delta;
660 #ifdef VERBB
661  cerr << "Send " << delta << " from " << u << " to " << v << endl;
662 #endif
663  if (!_active[v] && v != _t) {
665  _active_nodes[_labels[v]]->push_back(v);
666  _active[v]=true;
667  }
668  _excess[v]+=delta;
669  _flow[reverse[num_c]]-=delta;
670  } else {
671  m=MIN(m,_labels[v]+1);
672  }
673  }
674  ++pr;
675  }
676  num_relabels++;
677  if (_excess[u] > EPSILON_MAXFLOW) {
679  if (gap_heuristic) {
680  _all_nodes[_labels[u]]--;
681  if (_all_nodes[_labels[u]]==0) {
682  this->gap_relabelling(component,_labels[u],max_label);
683  _labels[u]=max_label;
684  } else {
685 #ifdef VERBB
686  cerr << "relabel " << u << " from " << _labels[u] << " to " << MIN(m,max_label) << endl;
687 #endif
688  _labels[u]=MIN(m,max_label);
689  _all_nodes[_labels[u]]++;
690  }
691  } else {
692 #ifdef VERBB
693  cerr << "relabel " << u << " from " << _labels[u] << " to " << MIN(m,max_label) << endl;
694 #endif
695  _labels[u]=MIN(m,max_label);
696  }
697  } else {
698  _excess[u]=0;
699  _current_edges[u]=((pr+curr) % nn);
700  }
701 };
702 
703 template <typename T>
705  int counter=1;
706  while (_current_max_label > 0 || !_active_nodes[0]->empty()) {
707  if (counter % 2*_N == 0) this->global_relabelling();
708  if (_active_nodes[_current_max_label]->empty()) {
709  _current_max_label--;
710  } else {
711  const int current_node=_active_nodes[_current_max_label]->front();
712  _active_nodes[_current_max_label]->pop_front();
713  _active[current_node]=false;
714  if (_excess[current_node] > EPSILON_MAXFLOW) {
715  this->discharge(NULL,current_node,_N);
716  if (_excess[current_node] > EPSILON_MAXFLOW && _labels[current_node] < _N) {
717  _active_nodes[_labels[current_node]]->push_back(current_node);
718  _active[current_node]=true;
719  if (_labels[current_node] > _current_max_label)
720  _current_max_label=_labels[current_node];
721  }
722  } else {
723  _excess[current_node]=0;
724  }
725  }
726  ++counter;
727  }
728 }
729 
730 template <typename T>
732  cerr << "Excess: " << endl;
733  for (int i= 0; i<_N; ++i) {
734  cerr << _excess[i] << " ";
735  }
736  cerr << endl;
737 
738 };
739 
740 
741 template <typename T>
742 void inline MaxFlow<T>::deactivate() {
743  for (int i= 0; i<_N; ++i) {
744  _seen[i]=true;
745  _active[i]=false;
746  _labels[i]=_N;
747  }
748 };
749 
750 template <typename T>
751 void inline MaxFlow<T>::deactivate(const list_int& component) {
752  for (const_iterator_int it=component.begin();
753  it != component.end(); ++it) {
754  _seen[*it]=true;
755  _active[*it]=false;
756  _labels[*it]=_N;
757  }
758 };
759 
760 
761 template <typename T>
763  cerr << "Labels: " << endl;
764  for (int i= 0; i<_N; ++i)
765  cerr << _labels[i] << " ";
766  cerr << endl;
767 
768 };
769 
770 template <typename T>
771 void inline MaxFlow<T>::print_graph() {
772  cerr << "Number of nodes: " << _N << endl;
773  cerr << "Source: " << _s << endl;
774  cerr << "Sink: " << _t << endl;
775  for (int i = 0; i<_N; ++i) _seen[i]=false;
776  this->print_graph_aux(_s);
777 };
778 
779 template <typename T>
780 void inline MaxFlow<T>::init_split_variables(SpMatrix<T>& splitted_w, const int Ng, const int Nv) {
781  for (int i = 0; i<_N; ++i) _seen[i]=false;
782  Vector<int> count(Ng);
783  int current = 0;
784  list_int** tab_list = new list_int*[Ng];
785  for (int i = 0; i<Ng; ++i) tab_list[i] = new list_int();
786  this->init_split_variables_aux(_s,current,count,tab_list,Ng,Nv);
787  int nzmax = 0;
788  for (int i = 0; i<Ng; ++i) {
789  nzmax += tab_list[i]->size();
790  }
792  splitted_w.resize(Nv,Ng,nzmax);
793  int* pB = splitted_w.pB();
794  int* r = splitted_w.r();
795  T* v = splitted_w.v();
796  pB[0]=0;
797  int counter=0;
798  for (int i = 0; i<Ng; ++i) {
799  pB[i+1]=pB[i]+tab_list[i]->size();
800  for (const_iterator_int it = tab_list[i]->begin(); it != tab_list[i]->end(); ++it) {
801  r[counter]= (*it);
802  v[counter++]=0;
803  }
804  }
805  for (int i = 0; i<Ng; ++i) delete(tab_list[i]);
806  delete[](tab_list);
807 };
808 
809 template <typename T>
811  for (int i = 0; i<_nzmax; ++i) _copycapacity[i]=_capacity[i];
812 }
813 template <typename T>
814 void inline MaxFlow<T>::save_flow() {
815  _copyflow=new T[_nzmax];
816  for (int i = 0; i<_nzmax; ++i) _copyflow[i]=_flow[i];
817  _copyexcess=new T[_N];
818  for (int i = 0; i<_N; ++i) _copyexcess[i]=_excess[i];
819 }
820 template <typename T>
822  for (int i = 0; i<_nzmax; ++i) _flow[i]=_copyflow[i];
823  delete[](_copyflow);
824  for (int i = 0; i<_N; ++i) _excess[i]=_copyexcess[i];
825  delete[](_copyexcess);
826 }
827 
828 
829 template <typename T>
831  for (int i = 0; i<_nzmax; ++i) _capacity[i]=_copycapacity[i];
832 }
833 
834 template <typename T>
835 bool inline MaxFlow<T>::check_flow() {
836  list_int tmp;
837  for (int i = 0; i<_N; ++i) _seen[i]=false;
838  tmp.push_back(_s);
839  _seen[_s]=true;
840 
841  bool correct=true;
842  T total_excess=0;
843  T total_excess2=0;
844  while (!tmp.empty()) {
845  const int node = tmp.front();
846  const int ind = _pr_node[node];
847  tmp.pop_front();
848  if (_excess[node] < 0) {
849  cerr << "negative excess: " <<_excess[node] << " on node " << node << endl;
850  correct=false;
851  }
852  T totalflow=0;
853  for (int i = 0; i<_num_edges[node]; ++i) {
854  totalflow+=_flow[ind+i];
855  if (_flow[ind+i] > _capacity[ind+i]) {
856  correct=false;
857  cerr << "exceed capacity on node " << node << " to " << _children[ind+i] << ". Flow: " << _flow[ind+i] << ", capacity: " << _capacity[ind+i] << endl;
858  total_excess += _flow[ind+i]-_capacity[ind+i];
859  }
860  if (!_seen[_children[ind+i]]) {
861  tmp.push_back(_children[ind+i]);
862  _seen[_children[ind+i]]=true;
863  }
864  }
865  if (node != _s && node != _t && abs(totalflow+_excess[node]) > EPSILON_MAXFLOW) {
866  cerr << "prb on node " << node << ", excess: " << _excess[node] << ", totalflow: " << totalflow << endl;
867  }
868  if (node != _s && node != _t)
869  total_excess2+=abs(totalflow+_excess[node]);
870  }
871  return correct;
872 }
873 
874 template <typename T>
875 void inline MaxFlow<T>::reset_flow() {
876  memset(_excess,0,_N*sizeof(T));
877  memset(_flow,0,_nzmax*sizeof(T));
878  _excess[_s]=INFINITY;
879 }
880 
881 template <typename T>
882 void inline MaxFlow<T>::scale_flow(const T scal) {
883  for (int i = 0; i<_N; ++i) _excess[i]*=scal;
884  for (int i = 0; i<_nzmax; ++i) _flow[i]*=scal;
885  _excess[_s]=INFINITY;
886 }
887 
888 template <typename T>
889 void inline MaxFlow<T>::set_weights(const T lambda) {
890  for (int j = 0; j<_num_edges[_s]; ++j) {
891  _capacity[_pr_node[_s]+j]=lambda;
892  }
893 };
894 
895 template <typename T>
896 void inline MaxFlow<T>::set_weights(const T* weights,
897  const T lambda) {
898  for (int j = 0; j<_num_edges[_s]; ++j) {
899  _capacity[_pr_node[_s]+j]=lambda*weights[j];
900  }
901 };
902 
903 template <typename T>
904 void inline MaxFlow<T>::print_sink() {
905  cerr << "Flow: ";
906  for (int j = 0; j<_num_edges[_t]; ++j) {
907  cerr << _flow[_reverse_address[_pr_node[_t]+j]] << " ";
908  }
909  cerr << endl;
910  cerr << "Capacity: ";
911  for (int j = 0; j<_num_edges[_t]; ++j) {
912  cerr << _capacity[_reverse_address[_pr_node[_t]+j]] << " ";
913  }
914  cerr << endl;
915 };
916 
917 template <typename T>
918 void inline MaxFlow<T>::print_component(const list_int& component) {
919  for (const_iterator_int it=component.begin();
920  it != component.end(); ++it) {
921  cerr << "Node: " << *it << endl;
922  cerr << "Children: ";
923  for (int j = 0; j<_num_edges[*it]; ++j) {
924  cerr << _children[_pr_node[*it]+j] << " ";
925  }
926  cerr << endl;
927  cerr << "Flow: ";
928  for (int j = 0; j<_num_edges[*it]; ++j) {
929  cerr << _flow[_pr_node[*it]+j] << " ";
930  }
931  cerr << endl;
932  cerr << "Capacity: ";
933  for (int j = 0; j<_num_edges[*it]; ++j) {
934  cerr << _capacity[_pr_node[*it]+j] << " ";
935  }
936  cerr << endl;
937  }
938 };
939 
940 template <typename T>
941 void inline MaxFlow<T>::sub_gradient_aux(const Vector<T>& input, Vector<T>& output, const Vector<T>& weights,
942  const int node, list_int& variables, const int Ng) {
943  _seen[node]=true;
944  const int ind = _pr_node[node];
945  const int* children = _children+ind;
946  const T* capacity = _capacity+ind;
947  for (int i = 0; i<_num_edges[node]; ++i) {
948  const int child=children[i];
949  if (child != _s && child != _t) {
950  if (child < Ng) {
951  if (capacity[i] > 0 && !_seen[child]) {
952  list_int new_var;
953  this->sub_gradient_aux(input,output,weights,child,new_var,Ng);
954  variables.fusion(new_var);
955  }
956  } else {
957  variables.push_back(child);
958  }
959  }
960  }
961  T max_abs = 0;
962  for (const_iterator_int it = variables.begin(); it != variables.end(); ++it) {
963  if (abs<T>(input[*it-Ng]) > max_abs) max_abs=abs<T>(input[*it-Ng]);
964  }
965  if (max_abs < 1e-15)
966  return;
967  list_int var_max;
968  for (const_iterator_int it = variables.begin(); it != variables.end(); ++it) {
969  if (abs<T>(abs<T>(input[*it-Ng])-max_abs) < 1e-15)
970  var_max.push_back(*it-Ng);
971  }
972  T scal = weights[node]/var_max.size();
973  for (const_iterator_int it = var_max.begin(); it != var_max.end(); ++it) {
974  output[*it] += input[*it] > 0 ? scal : -scal;
975  }
976 };
977 
978 template <typename T>
979 void inline MaxFlow<T>::sub_gradient(const Vector<T>& input, Vector<T>& output, const Vector<T>& weights, const int Ng) {
980  output.setZeros();
981  list_int tmp;
982  for (int i = 0; i<_N; ++i) {
983  _seen[i]=false;
984  if (i < Ng) tmp.push_back(i);
985  }
986  while (!tmp.empty()) {
987  const int node=tmp.front();
988  if (!_seen[node]) {
989  list_int variables;
990  this->sub_gradient_aux(input,output,weights,node,variables,Ng);
991  }
992  tmp.pop_front();
993  }
994 };
995 
996 template <typename T>
997 T inline MaxFlow<T>::norm(const T* variables, T* work, const T* weights, const int Ng, const bool linf) {
998  list_int tmp;
999  for (int i = 0; i<_N; ++i) {
1000  _seen[i]=false;
1001  work[i]=0;
1002  if (i < Ng) tmp.push_back(i);
1003  }
1004 
1005  while (!tmp.empty()) {
1006  const int node = tmp.front();
1007  if (_seen[node]) {
1008  tmp.pop_front();
1009  } else {
1010  if (node >= Ng && node != _s && node != _t) {
1011  work[node]= linf ? abs(variables[node-Ng]) : variables[node-Ng]*variables[node-Ng];
1012  _seen[node]=true;
1013  tmp.pop_front();
1014  } else {
1015  const int ind = _pr_node[node];
1016  const int* children = _children+ind;
1017  const T* capacity = _capacity+ind;
1018  bool all_child=true;
1019  for (int i = 0; i<_num_edges[node]; ++i) {
1020  const int child=children[i];
1021  if (child != _s && child != _t && capacity[i] > 0 && !_seen[child]) {
1022  all_child=false;
1023  tmp.push_front(children[i]);
1024  }
1025  }
1026  if (all_child) {
1027  T max_var=0;
1028  for (int i = 0; i<_num_edges[node]; ++i) {
1029  const int child=children[i];
1030  if (child != _s && child != _t && capacity[i] > 0) {
1031  max_var = linf ? MAX(max_var,work[child]) : max_var + work[child];
1032  }
1033  }
1034  work[node]=max_var;
1035  _seen[node]=true;
1036  }
1037  }
1038  }
1039  }
1040  T sum=0;
1041  if (linf) {
1042  for (int i = 0; i<Ng; ++i) {
1043  sum+=weights[i]*work[i];
1044  }
1045  } else {
1046  for (int i = 0; i<Ng; ++i) {
1047  sum+=weights[i]*sqrt(work[i]);
1048  }
1049  }
1050  return sum;
1051 };
1052 
1053 template <typename T>
1054 void inline MaxFlow<T>::print_component2(const list_int& component) {
1055  cerr << "*********Print component***********" << endl;
1056  for (const_iterator_int it=component.begin();
1057  it != component.end(); ++it) {
1058  cerr << *it << " ";
1059  }
1060  cerr << endl;
1061  cerr << "Excess" << endl;
1062  for (const_iterator_int it=component.begin();
1063  it != component.end(); ++it) {
1064  cerr << _excess[*it] << " ";
1065  }
1066  cerr << " " << _excess[_s] << " " << _excess[_t];
1067  cerr << endl;
1068  cerr << "Labels" << endl;
1069  for (const_iterator_int it=component.begin();
1070  it != component.end(); ++it) {
1071  cerr << _labels[*it] << " ";
1072  }
1073  cerr << " " << _labels[_s] << " " << _labels[_t];
1074  cerr << endl;
1075 
1076 
1077 };
1078 
1079 
1080 template <typename T>
1081 void inline MaxFlow<T>::print_graph_aux(const int i) {
1082  if (_seen[i]) return;
1083  cerr << endl;
1084  cerr << "Node: " << i << endl;
1085  _seen[i]=true;
1086  if (i == _t) return;
1087  cerr << "Children: ";
1088  for (int j = 0; j<_num_edges[i]; ++j) {
1089  cerr << _children[_pr_node[i]+j] << " ";
1090  }
1091  cerr << endl;
1092  cerr << "Capacity: ";
1093  for (int j = 0; j<_num_edges[i]; ++j) {
1094  cerr << _capacity[_pr_node[i]+j] << " ";
1095  }
1096  cerr << endl;
1097  cerr << "Flow: ";
1098  for (int j = 0; j<_num_edges[i]; ++j) {
1099  cerr << _flow[_pr_node[i]+j] << " ";
1100  }
1101  cerr << endl;
1102  cerr << "Rverse Flow: ";
1103  for (int j = 0; j<_num_edges[i]; ++j) {
1104  cerr << _flow[_reverse_address[_pr_node[i]+j]] << " ";
1105  }
1106  cerr << endl;
1107 
1108  for (int j = 0; j<_num_edges[i]; ++j) {
1109  this->print_graph_aux(_children[_pr_node[i]+j]);
1110  }
1111 };
1112 
1113 template <typename T>
1114 inline void MaxFlow<T>::init_split_variables_aux(const int i,int& current,
1115  Vector<int>& count, list_int** splitted_w, const int Ng, const int Nv) {
1116  if (_seen[i] || (i >= Ng && i != _s)) return;
1117  _seen[i]=true;
1118  const int ind = _pr_node[i];
1119  const int* children = _children+ind;
1120  const T* capacity = _capacity+ind;
1121 
1122  for (int j = 0; j<_num_edges[i]; ++j) {
1123  if (capacity[j] > 0) {
1124  this->init_split_variables_aux(children[j],current,count,splitted_w,Ng,Nv);
1125  }
1126  }
1127  if (i != _s) {
1128  Vector<T> tmp(Nv);
1129  tmp.setZeros();
1131  for (int j = 0; j<_num_edges[i]; ++j) {
1132  const int child=children[j];
1133  if (child != _s && child != _t && capacity[j] > 0) {
1134  if (child >= Ng) {
1135  tmp[child-Ng]=1.0;
1136  } else {
1137  for (const_iterator_int it = splitted_w[count[child]]->begin();
1138  it != splitted_w[count[child]]->end(); ++it)
1139  tmp[*it]++;
1140  }
1141  }
1142  }
1143  for (int j = 0; j<tmp.n(); ++j) {
1144  if (tmp[j]) splitted_w[current]->push_back(j);
1145  }
1146  count[i]=current;
1147  ++current;
1148  }
1149 };
1150 
1151 template <typename T>
1153  // global relabelling by reverse breadth first search
1154  list_int nodes;
1155  for (int i = 0; i<_N; ++i) _labels[i]=_N;
1156  for (int i = 0; i<_N; ++i) _seen[i]=false;
1157  nodes.push_back(_t);
1158  _seen[_t]=true;
1159  _labels[_t]=0;
1160  while (!nodes.empty()) {
1161  const int node=nodes.front();
1162  const int* children=_children+_pr_node[node];
1163  const int* reverse=_reverse_address+_pr_node[node];
1164  for (int i = 0; i<_num_edges[node]; ++i) {
1165  const int child=children[i];
1166  if (!_seen[child] && _capacity[reverse[i]] > _flow[reverse[i]]) {
1167  _seen[child]=true;
1168  const int new_label=_labels[node]+1;
1169  if (new_label != _labels[child] && _excess[child] > EPSILON_MAXFLOW) {
1170  _active_nodes[new_label]->push_back(child);
1171  _active[child]=true;
1172  if (new_label > _current_max_label)
1173  _current_max_label=new_label;
1174  }
1175  _labels[child]=new_label;
1176  nodes.push_back(child);
1177  }
1178  }
1179  nodes.pop_front();
1180  _active[node]=false;
1181  }
1182 };
1183 
1184 template <typename T>
1186  std::list< list_int* >& connex_components) {
1188  for (int i = 0; i<_N; ++i) _seen[i]=false;
1189  _seen[_s]=true;
1190  _seen[_t]=true;
1191  list_int tmp;
1192  for (int i = 0; i<_N; ++i) {
1193  if (!_seen[i]) {
1194  // create a component
1195  list_int* component = new list_int();
1196  tmp.push_back(i);
1197  while (!tmp.empty()) {
1198  int node=tmp.front();
1199  _seen[node]=true;
1200  component->push_back(node);
1201  tmp.pop_front();
1202  const int* children=_children+_pr_node[node];
1203  for (int i = 0; i<_num_edges[node]; ++i) {
1204  const int child=children[i];
1205  if (!_seen[child]) {
1206  _seen[child]=true;
1207  tmp.push_back(child);
1208  }
1209  }
1210  }
1211  connex_components.push_back(component);
1212  }
1213  }
1214 };
1215 
1216 template <typename T>
1217 T inline MaxFlow<T>::project_weighted(const list_int& component,
1218  const T* variables_in,T* variables_out,T* work, const T* weights,
1219  const int Ng) {
1220  T lambda=0;
1221  int num_var=0;
1222  Vector<T> ww(component.size());
1223  for (const_iterator_int it=component.begin();
1224  it != component.end(); ++it) {
1225  if (*it < Ng) {
1226  lambda+=_capacity[_reverse_address[_pr_node[*it]]];
1227  } else {
1228  ww[num_var]=T(1.0)/weights[*it-Ng];
1229  work[num_var++]=variables_in[*it-Ng];
1230  }
1231  }
1232  ww.setn(num_var);
1233  Vector<T> out;
1234  Vector<T> in(work,num_var);
1235  in.l1project_weighted(out,ww,lambda,true);
1236  T max_flow=0;
1237  int count=0;
1238  for (const_iterator_int it=component.begin();
1239  it != component.end(); ++it) {
1240  const int ind = _pr_node[*it];
1241  if (*it >= Ng) {
1242  const int nv=*it-Ng;
1243  variables_out[nv]=out[count];
1244  const T diff = (variables_in[nv]-variables_out[nv])*ww[count++];
1245  max_flow+=diff;
1246  _capacity[ind]=diff;
1247  if (_flow[ind] > diff) {
1248  _excess[*it]+=_flow[ind]-diff;
1249  _flow[ind]=diff;
1250  _flow[_reverse_address[ind]]=-diff;
1251  }
1252  _labels[*it]=1;
1253  }
1254  }
1255  return max_flow;
1256 
1257 };
1258 
1259 template <typename T>
1260 T inline MaxFlow<T>::project(const list_int& component,
1261  const T* variables_in,T* variables_out, T* work,
1262  const int Ng) {
1267  T lambda=0;
1268  int num_var=0;
1269  for (const_iterator_int it=component.begin();
1270  it != component.end(); ++it) {
1271  if (*it < Ng) {
1272  lambda+=_capacity[_reverse_address[_pr_node[*it]]];
1273  } else {
1274  work[num_var++]=variables_in[*it-Ng];
1275  }
1276  }
1277  // PRINT_F(lambda)
1278  T max_flow=0;
1279  const T thrs=this->compute_thrs_project_l1(work,num_var,lambda);
1280  for (const_iterator_int it=component.begin();
1281  it != component.end(); ++it) {
1282  const int ind = _pr_node[*it];
1283  if (*it >= Ng) {
1284  const int nv=*it-Ng;
1285  variables_out[nv]=MIN(variables_in[nv],thrs);
1286  const T diff = variables_in[nv]-variables_out[nv];
1287  max_flow+=diff;
1288  _capacity[ind]=diff;
1289  if (_flow[ind] > diff) {
1290  _excess[*it]+=_flow[ind]-diff;
1291  _flow[ind]=diff;
1292  _flow[_reverse_address[ind]]=-diff;
1293  }
1294  _labels[*it]=1;
1295  }
1296  }
1297  return max_flow;
1298 };
1299 
1300 template <typename T>
1301 T inline MaxFlow<T>::project_box(const list_int& component,
1302  const T* variables_in,T* variables_out,T* work, bool& fusion,
1303  const int Ng) {
1304  list_int nodes;
1305  list_int variables;
1306  _seen[_s]=true;
1307  _active[_s]=false;
1308  T lambda=0;
1309  int num_nodes=0;
1310  for (const_iterator_int it=component.begin();
1311  it !=component.end(); ++it) {
1312  const int node = *it;
1313  const int ind = _pr_node[node];
1314  _active[node]=true;
1315  _seen[node]=false;
1316  if (node < Ng) {
1317  work[node]=_capacity[_reverse_address[ind]];
1318  nodes.push_back(node);
1319  _all_nodes[node]=1;
1320  ++num_nodes;
1321  lambda+=work[node];
1322  } else {
1323  work[node]=0;
1324  variables.push_back(*it);
1325  }
1326  }
1327  // PRINT_F(lambda)
1328  fusion = num_nodes > 1;
1329  while (!nodes.empty()) {
1330  const int node = nodes.front();
1331  if (!_seen[node]) {
1332  const int ind = _pr_node[node];
1333  const int* childrens=_children+ind;
1334  const int* reverse=_reverse_address+ind;
1335  for (int& i = _all_nodes[node]; i<_num_edges[node]; ++i) {
1336  const int child = childrens[i];
1337  if (_active[child] && !_seen[child]
1338  && _capacity[reverse[i]] > 0) {
1339  nodes.push_front(child);
1340  break;
1341  }
1342  }
1343  if (_all_nodes[node]==_num_edges[node]) {
1344  _seen[node]=true;
1345  for (int i = 1; i<_num_edges[node]; ++i) {
1346  const int child = childrens[i];
1347  if (_active[child] && _capacity[ind+i] > 0) {
1348  work[child]+=work[node];
1349  }
1350  }
1351  nodes.pop_front();
1352  }
1353  } else {
1354  nodes.pop_front();
1355  }
1356  }
1357 
1358  T thrs = INFINITY;
1359  if (lambda > 0) {
1360  std::list<T> var;
1361  for (const_iterator_int it=variables.begin();
1362  it !=variables.end(); ++it) {
1363  if (variables_in[*it-Ng] > 0) {
1364  var.push_back(variables_in[*it-Ng]);
1365  T diff = variables_in[*it-Ng]-work[*it];
1366  if (diff > 0)
1367  var.push_back(-diff);
1368  }
1369  }
1370  var.sort(compare_abs<T>);
1371  int num=0;
1372  T sum=0;
1373  bool br=false;
1374  T pivot=0;
1375  for (typename std::list<T>::const_iterator it=var.begin();
1376  it != var.end(); ++it) {
1377  pivot=*it;
1378  sum+= pivot;
1379  num+= pivot > 0 ? 1 : -1;
1380  if (sum-abs<T>(*it)*num > lambda) {
1381  sum-=*it;
1382  num-= (*it > 0 ? 1 : -1);
1383  br=true;
1384  thrs= num==0 ? pivot : (sum-lambda)/num;
1385  break;
1386  }
1387  }
1388  if (!br) thrs=MAX(0,num==0 ? pivot : (sum-lambda)/num);
1389  }
1390  for (const_iterator_int it=variables.begin();
1391  it !=variables.end(); ++it) {
1392  variables_out[*it-Ng] = MIN(MAX(thrs,variables_in[*it-Ng]-work[*it]),
1393  variables_in[*it-Ng]);
1394  }
1395  T maxflow=0;
1396  for (const_iterator_int it=component.begin();
1397  it != component.end(); ++it) {
1398  const int ind = _pr_node[*it];
1399  if (*it >= Ng) {
1400  const int nv=*it-Ng;
1401  const T diff = variables_in[nv]-variables_out[nv];
1402  maxflow+=diff;
1403  _capacity[ind]=diff;
1404  if (_flow[ind] > diff) {
1405  _excess[*it]+=_flow[ind]-diff;
1406  _flow[ind]=diff;
1407  _flow[_reverse_address[ind]]=-diff;
1408  }
1409  _labels[*it]=1;
1410  }
1411  }
1412  return maxflow;
1413 };
1414 
1415 
1416 template <typename T>
1417 T inline MaxFlow<T>::flow_component(const list_int& component, const int Ng) {
1419  T max_flow=0;
1420  for (const_iterator_int it=component.begin();
1421  it != component.end(); ++it) {
1422  if (*it >= Ng) {
1423  max_flow+=_flow[_pr_node[*it]];
1424  }
1425  }
1427  return max_flow;
1428 };
1429 
1430 /*template <typename T>
1431  bool inline MaxFlow<T>::splitComponent2(const list_int& component,
1432  std::list< list_int* >& connex_components,const int Ng, bool* positive, const bool addpos) {
1433 
1434  }*/
1435 
1436 template <typename T>
1437 bool inline MaxFlow<T>::splitComponent(const list_int& component,
1438  std::list< list_int* >& connex_components,const int Ng, bool* positive, const bool addpos) {
1440  for (const_iterator_int it=component.begin();
1441  it != component.end(); ++it) {
1442  _seen[*it]=false;
1443  positive[*it]=false;
1444  }
1445  int num_comp=0;
1446  _seen[_s]=true;
1447  _seen[_t]=true;
1448  positive[_s]=true;
1449  positive[_t]=true;
1450  list_int tmp;
1452  for (const_iterator_int it=component.begin();
1453  it != component.end(); ++it) {
1454  if (!positive[*it] && _excess[*it] > EPSILON_MAXFLOW) {
1456  tmp.push_back(*it);
1457  positive[*it]=true;
1458  while (!tmp.empty()) {
1459  int node=tmp.front();
1460  tmp.pop_front();
1461  const int ind=_pr_node[node];
1462  const int* children=_children+ind;
1463  const T* flow=_flow+ind;
1464  const T* capacity=_capacity+ind;
1465  for (int i = 0; i<_num_edges[node]; ++i) {
1466  const int child=children[i];
1467  if (!_seen[child] && !positive[child] && (flow[i] < capacity[i]-EPSILON_MAXFLOW)) {
1468  positive[child]=true;
1469  tmp.push_back(child);
1470  }
1471  }
1472  }
1473  }
1474  }
1476  /*tmp.push_back(_s);
1477  while (!tmp.empty()) {
1478  int node=tmp.front();
1479  tmp.pop_front();
1480  const int ind=_pr_node[node];
1481  const int* children=_children+ind;
1482  const T* flow=_flow+ind;
1483  const T* capacity=_capacity+ind;
1484  for (int i = 0; i<_num_edges[node]; ++i) {
1485  const int child=children[i];
1486  if (!_seen[child] && !positive[child] && (flow[i] < capacity[i]-EPSILON_MAXFLOW)) {
1487  positive[child]=true;
1488  tmp.push_back(child);
1489  }
1490  }
1491  }*/
1492 
1494  for (const_iterator_int it=component.begin();
1495  it != component.end(); ++it) {
1496  if (positive[*it] && !_seen[*it]) {
1497  list_int* new_component = new list_int();
1499  tmp.push_back(*it);
1500  _seen[*it]=true;
1501  while (!tmp.empty()) {
1502  int node=tmp.front();
1503  new_component->push_back(node);
1504  tmp.pop_front();
1505  const int ind=_pr_node[node];
1506  const int* children=_children+ind;
1507  for (int i = 0; i<_num_edges[node]; ++i) {
1508  const int child=children[i];
1509  if (!positive[child] && child != _t) {
1510  _capacity[ind+i]=_capacity[ind+i] > 0 ? -0.5 : 0;
1511  }
1512  if (positive[child] && !_seen[child]) {
1513  _seen[child]=true;
1514  tmp.push_back(child);
1515  }
1516  }
1517  }
1518  if (addpos) {
1519  connex_components.push_back(new_component);
1520  } else {
1521  delete(new_component);
1522  }
1523  ++num_comp;
1524  }
1525  }
1527  for (const_iterator_int it=component.begin();
1528  it != component.end(); ++it) {
1529  if (!positive[*it] && !_seen[*it]) {
1530  list_int* new_component = new list_int();
1532  tmp.push_back(*it);
1533  _seen[*it]=true;
1534  while (!tmp.empty()) {
1535  int node=tmp.front();
1536  new_component->push_back(node);
1537  tmp.pop_front();
1538  const int ind=_pr_node[node];
1539  const int* children=_children+ind;
1540  for (int i = 0; i<_num_edges[node]; ++i) {
1541  const int child=children[i];
1542  if (positive[child] && child != _t) {
1543  //_capacity[ind+i]=-0.5;
1544  _capacity[ind+i]=_capacity[ind+i] > 0 ? -0.5 : 0;
1545  }
1546  if (!positive[child] && !_seen[child]) {
1547  _seen[child]=true;
1548  tmp.push_back(child);
1549  }
1550  }
1551  }
1552  connex_components.push_back(new_component);
1553  ++num_comp;
1554  }
1555  }
1556  if (num_comp == 1 && connex_components.size() != 0) {
1557  list_int* comp = connex_components.back();
1558  delete(comp);
1559  connex_components.pop_back();
1560  }
1561  return num_comp > 1;
1562  // cout << "Number of new component: " << num_comp << endl;
1563 };
1564 
1565 template <typename T>
1566 void inline MaxFlow<T>::reset_component(const list_int& component) {
1567  for (const_iterator_int it=component.begin();
1568  it != component.end(); ++it) {
1569  const int ind = _pr_node[*it];
1570  _excess[*it]=0;
1571  for (int i = 0; i<_num_edges[*it]; ++i) {
1572  _flow[i+ind]=0;
1573  _flow[_reverse_address[i+ind]]=0;
1574  }
1575  }
1576 };
1577 
1578 template <typename T>
1579 void inline MaxFlow<T>::perform_maxflow_component(const list_int& component) {
1580  tglobal3.start();
1581  int size_component=component.size();
1582  const int max_label=size_component+2;
1584  this->component_relabelling(component,max_label,true);
1585 #ifdef VERBB
1586  PRINT_I(_current_max_label)
1587  this->print_component2(component);
1588  this->print_component(component);
1589  stop();
1590 #endif
1591  int counter=1;
1593 
1594 
1595  while (_current_max_label > 0 || !_active_nodes[0]->empty()) {
1596 #ifdef VERBB
1597  this->print_component2(component);
1598  stop();
1599 #endif
1600  if (global_heuristic && (counter % (size_component+1)) == 0) {
1601  this->component_relabelling(component,max_label,false);
1602  ++counter;
1603  } else {
1604  if (_active_nodes[_current_max_label]->empty()) {
1605  _current_max_label--;
1606 #ifdef VERBB
1607  cerr << "current max label decreased to " << _current_max_label << endl;
1608 #endif
1609  } else {
1610  const int current_node=_active_nodes[_current_max_label]->front();
1611  _active_nodes[_current_max_label]->pop_front();
1612  _active[current_node]=false;
1613  if (_excess[current_node] > EPSILON_MAXFLOW) {
1614  this->discharge(component,current_node,max_label);
1615  if (_excess[current_node] > EPSILON_MAXFLOW && _labels[current_node] < max_label) {
1616  _active_nodes[_labels[current_node]]->push_back(current_node);
1617  _active[current_node]=true;
1618  if (_labels[current_node] > _current_max_label) {
1619  _current_max_label=_labels[current_node];
1620  }
1621  }
1622  } else {
1623  _excess[current_node]=0;
1624  }
1625  ++counter;
1626  }
1627  }
1628  }
1629 #ifdef VERBB
1630  cerr << "END max flow" << endl;
1631  this->print_excess();
1632  stop();
1633 #endif
1634  tglobal3.stop();
1635 };
1636 
1637 template <typename T>
1638 void inline MaxFlow<T>::gap_relabelling(const list_int& component, const int gap, const int max_label) {
1639 #ifdef VERBB
1640  cerr << "Gap relabelling " << gap << endl;
1641 #endif
1642  if (tglobal2.getElapsed() > 0.1*tglobal3.getElapsed()) return;
1643  tglobal2.start();
1644  num_gap_relabels++;
1645  for (const_iterator_int it = component.begin(); it != component.end(); ++it) {
1646  if (_labels[*it] > gap) {
1647  _labels[*it]=max_label;
1648  }
1649  }
1650  for (int i = gap; i<max_label; ++i) {
1651  _all_nodes[i]=0;
1652  }
1653  tglobal2.stop();
1654 };
1655 
1656 template <typename T>
1657 void inline MaxFlow<T>::component_relabelling(const list_int& component,
1658  const int max_label, const bool force) {
1659  tglobal1.start();
1660  if (!force && (tglobal1.getElapsed() > 0.1*tglobal3.getElapsed())) return;
1661  for (int i = 0; i<=component.size(); ++i)
1662  _active_nodes[i]->clear();
1663  if (gap_heuristic)
1664  for (int i = 0; i<=component.size(); ++i)
1665  _all_nodes[i]=0;
1666  _current_max_label=0;
1667  num_global_relabels++;
1669  list_int nodes;
1670  _labels[_t]=0;
1671  _all_nodes[0]++;
1672  _labels[_s]=max_label;
1673  _seen[_t]=true;
1674  _active[_t]=false;
1675  _seen[_s]=true;
1676  _active[_s]=false;
1677  // _seen[_s]=false;
1678  // _active[_s]=true;
1679 
1680  for (const_iterator_int it=component.begin();
1681  it != component.end(); ++it) {
1682  const int ind = _pr_node[*it];
1683  const int first_child=_children[ind];
1684  if (first_child==_t && _flow[ind] < _capacity[ind]) {
1685  _labels[*it]=1;
1686  nodes.push_back(*it);
1687  if (_excess[*it] > EPSILON_MAXFLOW) {
1688  _active_nodes[1]->push_back(*it);
1689  _current_max_label=1;
1690  _active[*it]=true;
1691  } else {
1692  _active[*it]=false;
1693  }
1694  if (gap_heuristic)
1695  _all_nodes[1]++;
1696  _seen[*it]=true;
1697  } else {
1699  if (first_child == _s && force) {
1700  const T delta = _capacity[_reverse_address[ind]] - _flow[_reverse_address[ind]];
1701  if (delta > 0) {
1702  _excess[*it] += delta;
1703  _flow[_reverse_address[ind]]=_capacity[_reverse_address[ind]];
1704  }
1705  }
1706  _seen[*it]=false;
1707  _active[*it]=false;
1708  _labels[*it]=max_label;
1709  }
1710  }
1711  while (!nodes.empty()) {
1712  const int node=nodes.front();
1713  const int* children=_children+_pr_node[node];
1714  const int* reverse=_reverse_address+_pr_node[node];
1715  for (int i = 0; i<_num_edges[node]; ++i) {
1716  const int child=children[i];
1717  if (!_seen[child] && _capacity[reverse[i]] > _flow[reverse[i]]) {
1718  _seen[child]=true;
1719  const int new_label=_labels[node]+1;
1720  if (new_label != _labels[child] && _excess[child] > EPSILON_MAXFLOW) {
1721  _active_nodes[new_label]->push_back(child);
1722  _active[child]=true;
1723  if (new_label > _current_max_label)
1724  _current_max_label=new_label;
1725  }
1726  _labels[child]=new_label;
1727  if (gap_heuristic)
1728  _all_nodes[new_label]++;
1729  nodes.push_back(child);
1730  }
1731  }
1732  nodes.pop_front();
1733  }
1734  tglobal1.stop();
1735  /* this->print_graph();
1736  this->print_excess();
1737  this->print_labels();
1738  stop();*/
1739 };
1740 
1741 template <typename T>
1742 void inline MaxFlow<T>::update_capacities(const list_int& component, T* work) {
1743  list_int comp_nodes;
1744  for (const_iterator_int it=component.begin();
1745  it != component.end(); ++it) {
1746  const int ind = _pr_node[*it];
1747  const int first_child=_children[ind];
1748  _all_nodes[*it]=0;
1749  _active[*it]=true;
1750  if (first_child == _t) {
1751  _seen[*it]=true;
1752  work[*it]=_capacity[ind];
1753  } else {
1754  _seen[*it]=false;
1755  comp_nodes.push_back(*it);
1756  }
1757  }
1758  list_int nodes;
1759  while (!comp_nodes.empty()) {
1760  const int new_node=comp_nodes.front();
1761  comp_nodes.pop_front();
1762  if (!_seen[new_node]) {
1763  nodes.push_back(new_node);
1764  while (!nodes.empty()) {
1765  const int node = nodes.front();
1766  _seen[node]=true;
1767  const int ind = _pr_node[node];
1768  const int* children=_children+ind;
1769  for ( ; _all_nodes[node] < _num_edges[node]; ++_all_nodes[node]) {
1770  const int child=children[_all_nodes[node]];
1771  if (_active[child] && !_seen[child] &&_capacity[ind+_all_nodes[node]] > 0) {
1772  nodes.push_front(child);
1773  break;
1774  }
1775  }
1776  if (_all_nodes[node]==_num_edges[node]) {
1777  work[node]=0;
1778  for (int i = 0; i < _num_edges[node]; ++i) {
1779  const int child=children[i];
1780  if (_active[child] && _capacity[ind+i] > 0) {
1781  if (work[child] > 0) {
1782  work[node]+=work[child];
1783  _capacity[ind+i] = MAX(_flow[ind+i],work[child]);
1784  } else {
1785  _capacity[ind+i]=-2;
1786  }
1787  }
1788  }
1789  nodes.pop_front();
1790  }
1791  }
1792  }
1793  }
1794 }
1795 template <typename T>
1796 void inline MaxFlow<T>::set_capacities_variables(const T* cap, const int Nv,
1797  const int Ng) {
1798  for (int i = 0; i<Nv; ++i) {
1799  const int ind = _pr_node[Ng+i];
1800  _capacity[ind]=abs(cap[i]);
1801  }
1802 };
1803 
1804 template <typename T>
1805 void inline MaxFlow<T>::set_capacities_groups(const list_int& component,
1806  const Vector<T>& weights,const T lambda, const int Ng) {
1807  for (const_iterator_int it = component.begin(); it != component.end();
1808  ++it) {
1809  if (*it < Ng) {
1810  _capacity[_reverse_address[_pr_node[*it]]]=lambda*weights[*it];
1811  }
1812  }
1813 };
1814 
1815 
1816 template <typename T>
1817 void inline MaxFlow<T>::restore_capacities(const list_int& component) {
1819  list_int nodes;
1820  _seen[_t]=true;
1821  _seen[_s]=true;
1822  for (const_iterator_int it=component.begin();
1823  it != component.end(); ++it) {
1824  _seen[*it]=false;
1825  }
1826  for (const_iterator_int it=component.begin();
1827  it != component.end(); ++it) {
1828  const int* children=_children+_pr_node[*it];
1829  T* capacity=_capacity+_pr_node[*it];
1830  for (int i = 0; i<_num_edges[*it]; ++i) {
1831  const int child=children[i];
1832  if (!_seen[child] && (capacity[i] > 0 || capacity[i] < -1))
1833  capacity[i]=INFINITY;
1834  }
1835  }
1836 };
1837 
1838 
1839 
1840 
1841 template <typename T>
1842 T inline MaxFlow<T>::compute_thrs_project_l1(T* X, const int n, const T lambda) {
1843  if (lambda==0) return INFINITY;
1844  T* prU = X;
1845  T sum = 0;
1846  int sum_card = n;
1847  for (int i = 0; i<sum_card; ++i) {
1848  if (X[i]) {
1849  sum += X[i];
1850  } else {
1851  swap(X[i],X[--sum_card]);
1852  --i;
1853  }
1854  }
1855  if (sum < lambda) {
1856  memset(X,0,sum_card*sizeof(T));
1857  return 0;
1858  }
1859  int sizeU = sum_card;
1860  sum_card = 0;
1861  sum=0;
1862 
1863  while (sizeU > 0) {
1864  // put the pivot in prU[0]
1865  swap(prU[0],prU[sizeU/2]);
1866  int sizeG=1;
1867  T sumG=prU[0];
1868 
1869  for (int i = 1; i<sizeU; ++i) {
1870  if (prU[i] >= prU[0]) {
1871  sumG += prU[i];
1872  swap(prU[sizeG++],prU[i]);
1873  }
1874  }
1875 
1876  T new_sum=sum+sumG;
1877  int new_card=sum_card+sizeG;
1878  if (new_sum - prU[0]*new_card <= lambda) {
1879  sum_card = new_card;
1880  sum = new_sum;
1881  prU +=sizeG;
1882  sizeU -= sizeG;
1883  } else {
1884  ++prU;
1885  sizeU = sizeG-1;
1886  }
1887  }
1888  return MAX(0,(sum-lambda)/sum_card);
1889 };
1890 
1891 template <typename T> class Graph {
1892  public:
1893  Graph();
1894  ~Graph();
1895 
1896  void inline create_graph(const int Nv, const int Ng,
1897  T* weights, mwSize* var_ir, mwSize* var_jc);
1898  void inline create_graph(const int Nv, const int Ng,
1899  T* weights, mwSize* gv_ir, mwSize* gv_jc, mwSize* gg_ir, mwSize* gg_jc);
1900 
1901  void inline proximal_operator(const T* variables_in, T* variables_out,const bool clever = false, const T* weights = NULL);
1902  void inline save_capacities() { _maxflow->save_capacities(); };
1903  void inline restore_capacities() { _maxflow->restore_capacities(); };
1904  void inline save_flow() { _maxflow->save_flow(); };
1905  void inline restore_flow() { _maxflow->restore_flow(); };
1906  void inline reset_flow() { _maxflow->reset_flow(); };
1907  void inline scale_flow(const T scal) { _maxflow->scale_flow(scal); };
1908  void inline set_weights(const T lambda) {
1909  _maxflow->set_weights(lambda); };
1910  void inline set_weights(const T* weights,
1911  const T lambda) {
1912  _maxflow->set_weights(weights,lambda); };
1913  void inline print() { _maxflow->print_graph(); };
1914  T inline norm(const T* variables, T* work, const T* weights, const bool linf=true) { return _maxflow->norm(variables,work,weights,_Ng,linf); };
1915  T inline dual_norm_inf(const Vector<T>& input, const Vector<T>& weights);
1916  void inline sub_gradient(const Vector<T>& input, Vector<T>& output, const Vector<T>& weights) {
1917  _maxflow->sub_gradient(input,output,weights,_Ng);
1918  }
1919  inline void init_split_variables(SpMatrix<T>& splitted_w) {
1920  _maxflow->init_split_variables(splitted_w,_Ng,_Nv);
1921  };
1922 
1923 
1924  private:
1925  int _Nv;
1926  int _Ng;
1927  T* _weights; // size Ng
1929 };
1930 
1931 template <typename T>
1933  _Nv=0;
1934  _Ng=0;
1935  _weights=NULL;
1936  _maxflow=NULL;
1937 };
1938 
1939 template <typename T>
1941  delete[](_weights);
1942  delete(_maxflow);
1943 };
1944 
1945 template <typename T>
1946 void inline Graph<T>::create_graph(const int Nv, const int Ng,
1947  T* weights, mwSize* var_ir, mwSize* var_jc) {
1948  _Nv=Nv;
1949  _Ng=Ng;
1950  _weights=new T[_Ng];
1951  for (int i = 0; i<_Ng; ++i) _weights[i]=weights[i];
1952  const int N = _Ng+_Nv+2;
1953  int* num_edges=new int[N];
1954  for (int i = 0; i<N; ++i) num_edges[i]=1;
1955  for (int i = 0; i<Ng; ++i) {
1956  for (int j = var_jc[i]; j<var_jc[i+1]; ++j) {
1957  num_edges[i]++;
1958  num_edges[Ng+var_ir[j]]++;
1959  }
1960  }
1961  const int s=_Ng+_Nv;
1962  const int t=_Ng+_Nv+1;
1963  num_edges[s]=_Ng;
1964  num_edges[t]=_Nv;
1965  _maxflow=new MaxFlow<T>(N, num_edges, s, t);
1966 
1967  for (int i = 0; i<_Ng; ++i)
1968  _maxflow->add_edge(s,i,_weights[i],0);
1969  for (int i = 0; i<_Nv; ++i)
1970  _maxflow->add_edge(_Ng+i,t,INFINITY,0);
1971  for (int i = 0; i<_Ng; ++i) {
1972  for (int j = var_jc[i]; j<var_jc[i+1]; ++j) {
1973  _maxflow->add_edge(i,_Ng+static_cast<int>(var_ir[j]),_weights[i],0);
1974  }
1975  }
1976  _maxflow->save_capacities();
1977  delete[](num_edges);
1978 };
1979 
1980 template <typename T>
1981 void inline Graph<T>::create_graph(const int Nv, const int Ng,
1982  T* weights, mwSize* gv_ir, mwSize* gv_jc, mwSize* gg_ir, mwSize* gg_jc) {
1983  _Nv=Nv;
1984  _Ng=Ng;
1985  _weights=new T[_Ng];
1986  for (int i = 0; i<_Ng; ++i) _weights[i]=weights[i];
1987  const int N = _Ng+_Nv+2;
1988  int* num_edges=new int[N];
1989  for (int i = 0; i<N; ++i) num_edges[i]=1;
1990  for (int i = 0; i<Ng; ++i) {
1991  for (int j = gv_jc[i]; j<static_cast<int>(gv_jc[i+1]); ++j) {
1992  num_edges[i]++;
1993  num_edges[Ng+gv_ir[j]]++;
1994  }
1995  }
1996  for (int i = 0; i<Ng; ++i) {
1997  for (int j = gg_jc[i]; j<static_cast<int>(gg_jc[i+1]); ++j) {
1998  if (i != static_cast<int>(gg_ir[j])) {
1999  num_edges[i]++;
2000  num_edges[gg_ir[j]]++;
2001  }
2002  }
2003  }
2004 
2005  const int s=_Ng+_Nv;
2006  const int t=_Ng+_Nv+1;
2007  num_edges[s]=_Ng;
2008  num_edges[t]=_Nv;
2009 
2010  _maxflow=new MaxFlow<T>(N, num_edges, s, t);
2011 
2012  for (int i = 0; i<_Ng; ++i)
2013  _maxflow->add_edge(s,i,_weights[i],0);
2014  for (int i = 0; i<_Nv; ++i)
2015  _maxflow->add_edge(_Ng+i,t,0,0);
2016  for (int i = 0; i<_Ng; ++i) {
2017  for (int j = gv_jc[i]; j<static_cast<int>(gv_jc[i+1]); ++j) {
2018  _maxflow->add_edge(i,_Ng+static_cast<int>(gv_ir[j]),INFINITY,0);
2019  }
2020  }
2021  for (int i = 0; i<_Ng; ++i) {
2022  for (int j = gg_jc[i]; j<static_cast<int>(gg_jc[i+1]); ++j) {
2023  if (i != static_cast<int>(gg_ir[j])) {
2024  _maxflow->add_edge(i,static_cast<int>(gg_ir[j]),INFINITY,0);
2025  }
2026  }
2027  }
2028  _maxflow->save_capacities();
2029  delete[](num_edges);
2030 };
2031 
2032 template <typename T>
2033 T inline Graph<T>::dual_norm_inf(const Vector<T>& input,
2034  const Vector<T>& weights) {
2035  // input.print("input");
2036  Timer time, time2;
2037  time.start();
2038  T* work = new T[_Nv+_Ng+2];
2039  bool* positive = new bool[_Ng+_Nv+2];
2040  _maxflow->set_capacities_variables(input.rawX(),_Nv,_Ng);
2041  std::list< list_int* > connex_components;
2042  _maxflow->extractConnexComponents(connex_components);
2043  _maxflow->deactivate();
2044  T tau = 0;
2045  int num=0;
2046  long num1=0;
2047  long num2=0;
2048  long num3=0;
2049  long num4=0;
2050 
2051  while (!connex_components.empty()) {
2052  ++num;
2053  list_int* component=connex_components.front();
2054  connex_components.pop_front();
2055  if (component->size() != 1) {
2056  // Compute budget and set up input capacities
2057  T sum_variables=0;
2058  T sum_weights=0;
2059  int size_list=0;
2060  for (const_iterator_int it = component->begin();
2061  it != component->end(); ++it) {
2062  if (*it < _Ng) {
2063  sum_weights+=weights[*it];
2064  ++size_list;
2065  } else {
2066  sum_variables+=abs<T>(input[*it-_Ng]);
2067  }
2068  }
2069  tau = MAX(tau,sum_variables/sum_weights);
2070  _maxflow->set_capacities_groups(*component,weights,tau,_Ng);
2071  if (cap_heuristic)
2072  _maxflow->update_capacities(*component,work);
2073  num_relabels=0;
2074  num_global_relabels=0;
2075  num_gap_relabels=0;
2076  _maxflow->perform_maxflow_component(*component);
2077  num1+=num_relabels;
2078  num2+=num_global_relabels;
2079  num3+=component->size();
2080  num4+=num_gap_relabels;
2081  T flow=_maxflow->flow_component(*component,_Ng);
2082  _maxflow->restore_capacities(*component);
2083  if (flow < (sum_variables-EPSILON_MAXFLOW)) {
2084  _maxflow->splitComponent(*component,connex_components,_Ng, positive,false);
2085  }
2086  _maxflow->deactivate(*component);
2087  }
2088  delete(component);
2089  }
2090  /*cerr << "num_comp: " << num << endl;
2091  cerr << "size_component: " << num3 << endl;
2092  cerr << "num_relabels: " << num1 << endl;
2093  cerr << "global: " << num2 << endl;
2094  cerr << "gap:: " << num4 << endl;
2095  cerr << "Time global" << endl;
2096  cerr << "Time dual" << endl;
2097  time.printElapsed();*/
2098 
2099  delete[](work);
2100  delete[](positive);
2101  return tau;
2102 };
2103 
2104 template <typename T>
2105 void inline Graph<T>::proximal_operator(const T* variables_in, T* variables_out,bool clever, const T* weights) {
2106 
2107  tglobal1.reset();
2108  tglobal2.reset();
2109  tglobal3.reset();
2110  Timer tprox;
2111  tprox.start();
2112 #ifdef VERB2
2113  PRINT_I(_Nv)
2114  PRINT_I(_Ng)
2115  PRINT_I(_maxflow->nzmax())
2116 #endif
2117  cap_heuristic = true;
2118  global_heuristic = true;
2119  gap_heuristic = true;
2120  std::list< list_int* > connex_components;
2121  _maxflow->extractConnexComponents(connex_components);
2122  T* work = new T[_Nv+_Ng+2];
2123  T* variables_bis = new T[_Nv];
2124  for (int i = 0; i<_Nv; ++i) variables_bis[i]=abs<T>(variables_in[i]);
2125  for (int i = 0; i<_Nv; ++i) variables_out[i]=variables_bis[i];
2126 
2127  /* cerr << "var out" << endl;
2128  for (int i = 0; i<_Nv; ++i)
2129  cerr << variables_out[i] << " ";
2130  cerr << endl;*/
2131  bool* positive = new bool[_Ng+_Nv+2];
2132  _maxflow->deactivate();
2133  T flow_missed=0;
2134  int num=1;
2135  long num1=0;
2136  long num2=0;
2137  long num3=0;
2138  long num4=0;
2139 
2140  Timer tsplit, tproj, tcap;
2141 
2142  while (!connex_components.empty()) {
2143  list_int* component=connex_components.front();
2144  connex_components.pop_front();
2145  if (component->size() != 1) {
2146  bool fusion=true;
2147  T budget;
2148 
2149  tproj.start();
2150  if (weights) {
2151  budget=_maxflow->project_weighted(*component,variables_bis,variables_out,work,weights,_Ng);
2152  } else {
2153  if (clever) {
2154  budget=_maxflow->project_box(*component,variables_bis,variables_out,work,fusion,_Ng);
2155  } else {
2156  budget=_maxflow->project(*component,variables_bis,variables_out,work,_Ng);
2157  }
2158  }
2159  tproj.stop();
2160  ++num;
2161  if (budget > EPSILON_MAXFLOW && fusion) {
2163  tcap.start();
2164  if (cap_heuristic)
2165  _maxflow->update_capacities(*component,work);
2166  tcap.stop();
2167  num_relabels=0;
2168  num_global_relabels=0;
2169  num_gap_relabels=0;
2170  _maxflow->perform_maxflow_component(*component);
2171  num1+=num_relabels;
2172  num2+=num_global_relabels;
2173  num3+=component->size();
2174  num4+=num_gap_relabels;
2175  _maxflow->restore_capacities(*component);
2176  T flow=_maxflow->flow_component(*component,_Ng);
2177  if (abs<T>(budget-flow)/budget > EPSILON_MAXFLOW) {
2179  tsplit.start();
2180  if (!_maxflow->splitComponent(*component,connex_components,_Ng, positive,true)) {
2181  flow_missed+=abs<T>(budget-flow);
2182  }
2183  tsplit.stop();
2184  }
2185  }
2186 #ifdef VERB3
2187  if (component->size() > 100000) {
2188  PRINT_I(component->size())
2189  cerr << "num_comp: " << num << endl;
2190  cerr << "size_component: " << num3 << endl;
2191  cerr << "num_relabels: " << num1 << endl;
2192  cerr << "global: " << num2 << endl;
2193  cerr << "gap:: " << num4 << endl;
2194  tglobal1.printElapsed();
2195  tglobal2.printElapsed();
2196  tglobal3.printElapsed();
2197  tcap.printElapsed();
2198  tproj.printElapsed();
2199  tsplit.printElapsed();
2200  }
2201 #endif
2202  _maxflow->deactivate(*component);
2203  }
2204  delete(component);
2205  }
2206 #ifdef VERB2
2207  cerr << "num_comp: " << num << endl;
2208  cerr << "size_component: " << num3 << endl;
2209  cerr << "num_relabels: " << num1 << endl;
2210  cerr << "global: " << num2 << endl;
2211  cerr << "gap:: " << num4 << endl;
2212  cerr << "Time global" << endl;
2213  tglobal1.printElapsed();
2214  tglobal2.printElapsed();
2215  tglobal3.printElapsed();
2216  tcap.printElapsed();
2217  tproj.printElapsed();
2218  tsplit.printElapsed();
2219  tprox.printElapsed();
2220 #endif
2221 
2222  /* cerr << "var out" << endl;
2223  for (int i = 0; i<_Nv; ++i)
2224  cerr << variables_out[i] << " ";
2225  cerr << endl;*/
2226  for (int i = 0; i<_Nv; ++i) variables_out[i] = variables_in[i] >= 0 ? MAX(variables_out[i],0) : -MAX(variables_out[i],0);
2227 
2228  delete[](positive);
2229  delete[](variables_bis);
2230  delete[](work);
2231 };
2232 
2233 template <typename T> struct GraphStruct {
2238  int Nv;
2239  int Ng;
2241 };
2242 
2243 template <typename T> struct TreeStruct {
2249  int Nv;
2250  int Ng;
2251 };
2252 
2253 template <typename T> struct GraphPathStruct {
2254  GraphPathStruct() { ir=NULL; jc=NULL; n=0; m=0;
2255  precision=std::numeric_limits<long long>::max(); weights=NULL;
2256  start_weights=NULL; stop_weights=NULL; //num_fixed=0;
2257  //indices=NULL;
2258  };
2259  mwSize* ir;
2261  int n;
2262  int m;
2263  long long precision;
2267 // int num_fixed;
2268 // int* indices;
2269 };
2270 
2271 template <typename Int=long long>
2272 struct Path {
2275  double flow;
2276 };
2277 
2278 template <typename Int = long long> class MinCostFlow {
2279 
2280  public:
2281  MinCostFlow(const int n, const int* max_num_arcs);
2282  ~MinCostFlow();
2283 
2284  void inline add_edge(const int u, const int v, const Int cost, const double double_cost, const Int cap);
2285  void inline set_demand(const int node, const Int dem) { _demand[node]=dem; };
2286  void inline set_edge(const int node, const int num_arc, const Int cost, const Int cap);
2287  void inline set_capacity(const int node, const int num_arc, const Int cap);
2288  void inline add_flow(const int node, const int num_arc, const Int flow);
2289  void inline set_quad_cost(const int node, const int num_arc, const bool quad_cost) {
2290  _quad_cost[_pr_node[node]+num_arc]=quad_cost;
2291  _quad_cost[_reverse[_pr_node[node]+num_arc]]=quad_cost;
2292  };
2293  void inline set_is_quad_cost(const bool is_quad_cost) { _is_quadratic_cost=is_quad_cost; };
2294  void inline discharge(const int node, const Int eps);
2295  void save_costs();
2296  void restore_costs();
2297  void scale_costs(const double scal);
2298  Int compute_cost() const;
2299  double compute_cost_double() const;
2300  Int compute_uncap_cost() const;
2301  Int inline get_flow(const int node, const int num_arc) const { return _flow[_pr_node[node]+num_arc]; };
2302 
2303  void compute_min_cost(const bool scale_data = true, const bool verbose=false);
2304  Int refine(Int eps, const bool price_refine = false);
2305  void price_update(const Int eps);
2306  bool price_refine(const Int eps);
2307 
2308  bool test_optimality_conditions() const;
2309 
2310  void inline print_excess() const;
2311  void inline print_prices() const;
2312  void inline print_graph() const;
2313  bool inline topological_sort(const bool admissible = false, bool* admiss = NULL, Int* rcosts = NULL);
2314  Int inline reduced_cost(const int node, const int child, const int arc) const;
2315 
2316  Int cost_shortest_path_in_dag(list_int& path);
2317  void st_flow_decomposition_dag(List<Path<Int>*>& list, const int s, const int t) const;
2318  void print_dimacs(const char* name) const;
2319 
2320  private:
2321  int _n;
2322  int _m;
2323 
2325  double _alpha;
2326 
2327  Int* _prices;
2328  Int* _excess;
2329  Int* _demand;
2330  bool* _active;
2331 
2334  int* _pr_node;
2336  int* _reverse;
2337  Int* _flow;
2339  Int* _cost;
2342  int _maxm;
2343 
2346 
2349  bool* _quad_cost;
2352 };
2353 
2354 template <typename Int>
2355 MinCostFlow<Int>::MinCostFlow(const int n, const int* max_num_arcs) {
2356  _n=n;
2357  _m=0;
2358  _max_cost=0;
2359  _alpha=16.0;
2360  _is_quadratic_cost=false;
2361 
2362  _prices=new Int[n];
2363  memset(_prices,0,n*sizeof(Int));
2364  _excess=new Int[n];
2365  memset(_excess,0,n*sizeof(Int));
2366  _demand=new Int[n];
2367  memset(_demand,0,n*sizeof(Int));
2368  _active=new bool[n];
2369  memset(_active,false,n*sizeof(bool));
2370 
2371  _topological_order=new int[n];
2372  memset(_topological_order,0,n*sizeof(int));
2373  _topologically_sorted=false;
2374  _num_arcs=new int[n];
2375  memset(_num_arcs,0,n*sizeof(int));
2376  _max_num_arcs=new int[n];
2377  memcpy(_max_num_arcs,max_num_arcs,n*sizeof(int));
2378  _pr_node=new int[n];
2379  _maxm=0;
2380  for (int i = 0; i<n; ++i) {
2381  _pr_node[i]=_maxm;
2382  _maxm+=_max_num_arcs[i];
2383  }
2384  _children=new int[_maxm];
2385  memset(_children,-1,_maxm*sizeof(int));
2386  _reverse=new int[_maxm];
2387  memset(_reverse,-1,_maxm*sizeof(int));
2388  _flow=new Int[_maxm];
2389  memset(_flow,0,_maxm*sizeof(Int));
2390  _capacity=new Int[_maxm];
2391  memset(_capacity,0,_maxm*sizeof(Int));
2392  _cost=new Int[_maxm];
2393  memset(_cost,0,_maxm*sizeof(Int));
2394  _save_cost=new Int[_maxm];
2395  memset(_save_cost,0,_maxm*sizeof(Int));
2396  _init_double_cost=new double[_maxm];
2397  memset(_init_double_cost,0,_maxm*sizeof(double));
2398  _quad_cost=new bool[_maxm];
2399  memset(_quad_cost,false,_maxm*sizeof(bool));
2400 };
2401 
2402 template <typename Int>
2404  delete[](_prices);
2405  delete[](_excess);
2406  delete[](_demand);
2407  delete[](_topological_order);
2408  delete[](_num_arcs);
2409  delete[](_max_num_arcs);
2410  delete[](_pr_node);
2411  delete[](_children);
2412  delete[](_reverse);
2413  delete[](_flow);
2414  delete[](_capacity);
2415  delete[](_cost);
2416  delete[](_save_cost);
2417  delete[](_init_double_cost);
2418  delete[](_active);
2419  delete[](_quad_cost);
2420 }
2421 
2422 template <typename Int>
2423 void inline MinCostFlow<Int>::add_edge(const int u, const int v, const Int cost, const double double_cost, const Int cap) {
2424  const int pu=_pr_node[u];
2425  const int pv=_pr_node[v];
2426  const int nu=_num_arcs[u]+pu;
2427  const int nv=_num_arcs[v]+pv;
2428  _children[nu]=v;
2429  _children[nv]=u;
2430  _capacity[nu]=cap;
2431  _capacity[nv]=0;
2432  _cost[nu]=cost;
2433  _cost[nv]=-cost;
2434  _init_double_cost[nu]=double_cost;
2435  _init_double_cost[nv]=-double_cost;
2436  _reverse[nu]=nv;
2437  _reverse[nv]=nu;
2438  _num_arcs[u]++;
2439  _num_arcs[v]++;
2440 };
2441 
2442 template <typename Int>
2443 void inline MinCostFlow<Int>::set_edge(const int node, const int num_arc,
2444  const Int cost, const Int cap) {
2445  const int pu=_pr_node[node];
2446  const int nu=pu+num_arc;
2447  _cost[nu]=cost;
2448  _capacity[nu]=cap;
2449  _cost[_reverse[nu]]=-cost;
2450  _capacity[_reverse[nu]]=0;
2451 };
2452 
2453 template <typename Int>
2454 void inline MinCostFlow<Int>::set_capacity(const int node, const int num_arc,
2455  const Int cap) {
2456  const int pu=_pr_node[node];
2457  const int nu=pu+num_arc;
2458  _capacity[nu]=cap;
2459  _capacity[_reverse[nu]]=0;
2460 };
2461 
2462 template <typename Int>
2463 void inline MinCostFlow<Int>::add_flow(const int node, const int num_arc, const Int flow) {
2464  const int nu=_pr_node[node]+num_arc;
2465  _flow[nu]+=flow;
2466  _flow[_reverse[nu]]-=flow;
2467 };
2468 
2469 template <typename Int>
2471  memcpy(_save_cost,_cost,_maxm*sizeof(Int));
2472 };
2473 
2474 template <typename Int>
2476  memcpy(_cost,_save_cost,_maxm*sizeof(Int));
2477 };
2478 
2479 template <typename Int>
2480 void MinCostFlow<Int>::scale_costs(const double scal) {
2481  // TODO: should maybe change sf?
2482  for (int i = 0;i<_maxm; ++i) {
2483  _cost[i]=static_cast<Int>(ceil(scal*_init_double_cost[i]));
2484  }
2485 };
2486 
2487 template <typename Int>
2488 void MinCostFlow<Int>::compute_min_cost(const bool scale_data, const bool verbose) {
2489  _time1.reset();
2490  _time1.start();
2491  _time2.reset();
2492  _time2.stop();
2493  _max_cost=0;
2494  Int eps=0;
2495  tglobal1.reset();
2496  tglobal1.start();
2497  tglobal2.reset();
2498  tglobal2.stop();
2499  tglobal3.reset();
2500  tglobal3.stop();
2501 
2502  if (scale_data) {
2503  for (int i = 0; i<_maxm; ++i) _cost[i] *= _n;
2504  for (int i = 0; i<_maxm; ++i) _capacity[i] *= _n;
2505  for (int i = 0; i<_n; ++i) _demand[i] *= _n;
2506  }
2507 
2508  for (int i=0; i< _maxm; ++i) if (_cost[i] > eps) eps=_cost[i];
2509  memset(_prices,0,_n*sizeof(Int));
2510  memset(_flow,0,_maxm*sizeof(Int));
2511  memset(_active,false,_n*sizeof(bool));
2512  for (int i=0; i<_n; ++i) _excess[i]=-_demand[i];
2513  num_relabels=0;
2514  num_pushes=0;
2515 
2516  bool price_refine=false;
2517  while (eps > 1) {
2518 // cerr << "eps " << eps << endl;
2519  eps=this->refine(eps,price_refine);
2520  price_refine=true;
2521  }
2522  if (scale_data) {
2523  for (int i = 0; i<_maxm; ++i) _cost[i] /= _n;
2524  for (int i = 0; i<_maxm; ++i) _capacity[i] /= _n;
2525  for (int i = 0; i<_n; ++i) _demand[i] /= _n;
2526  for (int i = 0; i<_maxm; ++i) _flow[i] /= _n;
2527  for (int i = 0; i<_n; ++i) _prices[i] /= _n;
2528  }
2529  tglobal1.stop();
2530  _time1.stop();
2531  if (verbose) {
2532  cerr << "Num pushes: " << num_pushes << ", num relabels: " << num_relabels << endl;
2533  tglobal1.printElapsed();
2534  cerr << "Time for price updates" << endl;
2535  tglobal2.printElapsed();
2536  cerr << "Time for price refines" << endl;
2537  tglobal3.printElapsed();
2538  }
2539 };
2540 
2541 template <typename Int>
2542 Int MinCostFlow<Int>::refine(Int eps, const bool price_refine) {
2543 // cerr << eps << endl;
2544 // cerr << "Num pushes: " << num_pushes << ", num relabels: " << num_relabels << endl;
2545  eps=static_cast<Int>(ceil(static_cast<double>(eps)/_alpha));
2546  if (price_refine_heuristic && price_refine && this->price_refine(eps)) return eps;
2547 
2548  for (int i = 0; i<_n; ++i) {
2549  const int pr_begin=_pr_node[i];
2550  const int pr_end=_pr_node[i]+_num_arcs[i];
2551  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2552  const int child=_children[pointer];
2553  if (_is_quadratic_cost && _quad_cost[pointer]) {
2554  const Int reduced_cost=_flow[pointer]+_cost[pointer]+_prices[i]-_prices[child];
2555  if (reduced_cost < 0) {
2556  const Int delta=MIN(_capacity[pointer]-_flow[pointer],-reduced_cost);
2557  assert(delta >= 0);
2558  if (delta != 0) {
2559  _excess[i]-=delta;
2560  _excess[child]+=delta;
2561  _flow[pointer] += delta;
2562  _flow[_reverse[pointer]] -=delta;
2563  }
2564  }
2565  } else {
2566  const Int reduced_cost=_cost[pointer]+_prices[i]-_prices[child];
2567  if (reduced_cost < 0) {
2568  const Int delta=_capacity[pointer]-_flow[pointer];
2569  if (delta != 0) {
2570  _excess[i]-=delta;
2571  _excess[child]+=delta;
2572  _flow[pointer] = _capacity[pointer];
2573  _flow[_reverse[pointer]]=-_capacity[pointer];
2574  }
2575  }
2576  }
2577  }
2578  }
2579 
2580  for (int i = 0; i<_n; ++i)
2581  if (_excess[i] > 0 && !_active[i]) {
2582  _list_active.push_back(i);
2583  _active[i]=true;
2584  }
2585 
2586  while (!_list_active.empty()) {
2587  if (price_heuristic && (_time2.getElapsed()/_time1.getElapsed() < 0.5)) this->price_update(eps);
2588  const int node = _list_active.front();
2589  _list_active.pop_front();
2590  _active[node]=false;
2591  this->discharge(node,eps);
2592  }
2593  return eps;
2594 };
2595 
2596 template <typename Int>
2597 void inline MinCostFlow<Int>::price_update(const Int eps) {
2598  tglobal2.start();
2599  _time2.start();
2600  //this->print_prices();
2601  Int* rank = new Int[_n];
2602  Int* scanned = new Int[_n];
2603  Int* temp_scanned = new Int[_n];
2604  BinaryHeap<Int> heap(_n);
2605  memset(scanned,false,_n*sizeof(Int));
2606  memset(temp_scanned,false,_n*sizeof(Int));
2607  Int total_excess=0;
2608  for (int i = 0; i<_n; ++i) {
2609  if (_excess[i] < 0) {
2610  rank[i]=0;
2611  temp_scanned[i]=true;
2612  heap.insert(i,0);
2613  total_excess-=_excess[i];
2614  } else {
2616  }
2617  }
2618 
2619  while (!heap.is_empty()) {
2620  int node;
2621  Int rank_node;
2622  heap.find_min(node,rank_node);
2623  heap.delete_min();
2624  scanned[node]=true;
2625  if (_excess[node] > 0) total_excess-=_excess[node];
2626  if (total_excess==0) break;
2627  const int pr_begin=_pr_node[node];
2628  const int pr_end=_pr_node[node]+_num_arcs[node];
2629  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2630  const int child = _children[pointer];
2631  if (!scanned[child] && _flow[_reverse[pointer]] < _capacity[_reverse[pointer]]) {
2632  const Int reduced_cost=this->reduced_cost(node,child,pointer);
2633  if (reduced_cost >= 0) {
2634  if (temp_scanned[child]) {
2635  if (rank[node]<rank[child])
2636  heap.decrease_key(child,rank[node]);
2637  } else {
2638  heap.insert(child,rank[node]);
2639  temp_scanned[child]=true;
2640  }
2641  rank[child]=rank[node];
2642  } else {
2643  const Int new_rank=rank[node]-reduced_cost;
2644  if (temp_scanned[child]) {
2645  if (new_rank < rank[child]) {
2646  rank[child]=new_rank;
2647  heap.decrease_key(child,rank[child]);
2648  }
2649  } else {
2650  temp_scanned[child]=true;
2651  rank[child]=new_rank;
2652  heap.insert(child,rank[child]);
2653  }
2654  }
2655  }
2656  }
2657  }
2658 
2659  Int max_rank=0;
2660  for (int i = 0; i<_n; ++i) {
2661  if (scanned[i] && rank[i] > max_rank) max_rank=rank[i];
2662  }
2663 
2664  //this->print_graph();
2665  const Int max_increase=max_rank;
2666  for (int i = 0; i<_n; ++i) {
2667  assert(rank[i] >= 0);
2668  _prices[i] -= rank[i] > max_rank ? max_increase : rank[i];
2669  }
2670 
2671  delete[](rank);
2672  delete[](scanned);
2673  delete[](temp_scanned);
2674 
2675  tglobal2.stop();
2676  _time2.stop();
2677 };
2678 
2679 template <typename Int>
2680 void inline MinCostFlow<Int>::discharge(const int node, const Int eps) {
2681  if (_excess[node] <= 0) return;
2682  // sequence of pushes
2683  Int max_cmp_cost=-std::numeric_limits<Int>::max();
2684  const int pr_begin=_pr_node[node];
2685  const int pr_end=_pr_node[node]+_num_arcs[node];
2686  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2687  const Int cap_residual=_capacity[pointer]-_flow[pointer];
2688  const int child=_children[pointer];
2689  if (cap_residual > 0) {
2690  if (_is_quadratic_cost && _quad_cost[pointer]) {
2691  const Int reduced_cost=_flow[pointer]+_cost[pointer]+_prices[node]-_prices[child];
2692  if (reduced_cost < 0) {
2693  num_pushes++;
2694  const Int delta=MIN(MIN(cap_residual,-reduced_cost),_excess[node]);
2695  _excess[node]-=delta;
2696  _excess[child]+=delta;
2697  _flow[pointer] += delta;
2698  _flow[_reverse[pointer]] -= delta;
2699  if (!_active[child]) {
2700  _active[child]=true;
2701  _list_active.push_back(child);
2702  }
2703  if (delta==-reduced_cost) {
2704  max_cmp_cost=MAX(max_cmp_cost,_prices[node]);
2705  }
2706  } else {
2707  max_cmp_cost=MAX(max_cmp_cost,_prices[node]-reduced_cost);
2708  }
2709  if (!_excess[node]) break;
2710  } else {
2711  const Int compare_cost=_prices[child]-_cost[pointer];
2712  if (compare_cost > _prices[node]) {
2713  num_pushes++;
2714  Int delta;
2715  if (_excess[node] > cap_residual) {
2716  delta=cap_residual;
2717  _excess[node]-=delta;
2718  } else {
2719  delta=_excess[node];
2720  _excess[node]=0;
2721  }
2722  _excess[child]+=delta;
2723  _flow[pointer] += delta;
2724  _flow[_reverse[pointer]] -= delta;
2725  if (!_active[child]) {
2726  _active[child]=true;
2727  _list_active.push_back(child);
2728  }
2729  if (!_excess[node]) break;
2730  } else {
2731  max_cmp_cost=MAX(max_cmp_cost,compare_cost);
2732  }
2733  }
2734  }
2735  }
2736  // relabel
2737  if (_excess[node] > 0) {
2738  num_relabels++;
2739  _prices[node]=max_cmp_cost-eps;
2740  _list_active.push_front(node);
2741  _active[node]=true;
2742  }
2743 };
2744 
2745 template <typename Int>
2747  Int min_prb=0;
2748  for (int i = 0; i<_n; ++i) {
2749  const int pr_begin=_pr_node[i];
2750  const int pr_end=_pr_node[i]+_num_arcs[i];
2751  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2752  const Int cap_residual=_capacity[pointer]-_flow[pointer];
2753  if (cap_residual > 0) {
2754  const int child=_children[pointer];
2755  const Int reduced_cost=this->reduced_cost(i,child,pointer);
2756  min_prb=MIN(min_prb,reduced_cost);
2757  }
2758  }
2759  }
2760  cerr << "Flow is " << -min_prb << "-optimal" << endl;
2761  return !min_prb;
2762 };
2763 
2764 template <typename Int>
2766  Int cost=0;
2767  for (int i = 0; i<_n; ++i) {
2768  const int pr_begin=_pr_node[i];
2769  const int pr_end=_pr_node[i]+_num_arcs[i];
2770  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2771  cost+=_flow[pointer]*_cost[pointer];
2772  }
2773  }
2774  return cost;
2775 };
2776 
2777 template <typename Int>
2779  double cost=0;
2780  for (int i = 0; i<_n; ++i) {
2781  const int pr_begin=_pr_node[i];
2782  const int pr_end=_pr_node[i]+_num_arcs[i];
2783  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2784  cost+=static_cast<double>(_flow[pointer])*static_cast<double>(_cost[pointer]);
2785  }
2786  }
2787  return cost;
2788 };
2789 
2790 
2791 template <typename Int>
2793  Int cost=0;
2794  for (int i = 0; i<_n; ++i) {
2795  cost += _prices[i]*_demand[i];
2796  }
2797  return cost;
2798 };
2799 
2800 template <typename Int>
2801 bool MinCostFlow<Int>::price_refine(const Int eps) {
2802  tglobal3.start();
2803  // cerr << "Start price refine" << endl;
2804  bool* admiss = new bool[_maxm];
2805  Int* reduced_costs = new Int[_maxm];
2806  Int* distances = new Int[_n];
2807  bool* scanned = new bool[_n];
2808  bool acyclic=true;
2809  bool optimal=false;
2810  BinaryHeap<Int> heap(_n);
2811  const Int infinity=std::numeric_limits<Int>::max();
2812 
2813  int iter=0;
2814  while (iter < 2) {
2815  ++iter;
2816  acyclic=this->topological_sort(true,admiss,reduced_costs);
2817  if (!acyclic) break;
2818  optimal=true;
2819  for (int i = 0; i<_maxm; ++i) {
2820  if (admiss[i] && reduced_costs[i] < -eps) { optimal=false; break; }
2821  }
2822  if (iter==2) break;
2823  if (optimal) break;
2824  memset(distances,0,_n*sizeof(Int));
2825  distances[_topological_order[0]]=0;
2826  for (int i = 0; i<_n; ++i) {
2827  const int node = _topological_order[i];
2828  const int pr_begin=_pr_node[node];
2829  const int pr_end=_pr_node[node]+_num_arcs[node];
2830  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2831  if (admiss[pointer]) {
2832  const int child = _children[pointer];
2833  const Int new_cost=distances[node] + reduced_costs[pointer]; // : distances[node] + MIN(reduced_costs[pointer]+eps,0);
2834  if (distances[child] > new_cost) {
2835  distances[child]=new_cost;
2836  }
2837  }
2838  }
2839  heap.insert(node,distances[node]);
2840  }
2841 
2842  memset(scanned,false,_n*sizeof(bool));
2843  while (!heap.is_empty()) {
2844  int node;
2845  Int rank_node;
2846  heap.find_min(node,rank_node);
2847  heap.delete_min();
2848  scanned[node]=true;
2849  const int pr_begin=_pr_node[node];
2850  const int pr_end=_pr_node[node]+_num_arcs[node];
2851  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2852  const int child = _children[pointer];
2853  const Int reduced_cost=reduced_costs[pointer];
2854  if (!scanned[child] && _capacity[pointer] > _flow[pointer]) {
2855  if (reduced_cost < 0) {
2856  if (distances[child] > distances[node]) {
2857  distances[child]=distances[node];
2858  heap.decrease_key(child,distances[node]);
2859  }
2860  } else {
2861  const Int new_dist = distances[node]+eps*(reduced_cost/eps); // : distances[node]+reduced_cost+eps;
2862  if (distances[child] > new_dist) {
2863  distances[child]=new_dist;
2864  heap.decrease_key(child,new_dist);
2865  }
2866  }
2867  }
2868  }
2869  }
2870  Int max_distances=-infinity;
2871  Int min_distances=infinity;
2872  for (int i = 0; i<_n; ++i) {
2873  if (distances[i] < min_distances) min_distances=distances[i];
2874  if (distances[i] > max_distances) max_distances=distances[i];
2875  }
2876  // this->print_graph();
2877 
2878  if (min_distances==max_distances) break;
2879  for (int i = 0; i<_n; ++i) {
2880  _prices[i] += distances[i]-max_distances;
2881  }
2882  break;
2883  }
2884 
2885  delete[](admiss);
2886  delete[](reduced_costs);
2887  delete[](distances);
2888  delete[](scanned);
2889  tglobal3.stop();
2890  return optimal;
2891 }
2892 
2893 template <typename Int>
2895  if (!_topologically_sorted) this->topological_sort();
2896  Int* distances = new Int[_n];
2897  int* prec = new int[_n];
2898  for (int i = 0; i < _n; ++i) prec[i]=-1;
2899  const Int infinity=std::numeric_limits<Int>::max();
2900  for (int i = 0; i < _n; ++i) distances[i]=infinity;
2901  distances[_topological_order[0]]=0;
2902  for (int i = 0; i < _n; ++i) {
2903  const int node = _topological_order[i];
2904  const int pr_begin=_pr_node[node];
2905  const int pr_end=_pr_node[node]+_num_arcs[node];
2906  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2907  if (_capacity[pointer] > 0) {
2908  const int child = _children[pointer];
2909  const Int new_cost= distances[node] + _cost[pointer];
2910  if (distances[child] > new_cost) {
2911  distances[child]=new_cost;
2912  prec[child]=node;
2913  }
2914  }
2915  }
2916  }
2917  const Int shortest_path=distances[_topological_order[_n-1]];
2918  int current=_topological_order[_n-1];
2919  list_path.clear();
2920  while (current != -1) {
2921  list_path.push_front(current);
2922  current=prec[current];
2923  }
2924  delete[](distances);
2925  delete[](prec);
2926  return shortest_path;
2927 };
2928 
2929 template <typename Int>
2930 void MinCostFlow<Int>::st_flow_decomposition_dag(List<Path<Int>*>& decomposition, const int s, const int t) const {
2931  const int pr_begin=_pr_node[s];
2932  const int pr_end=_pr_node[s]+_num_arcs[s];
2933  BinaryHeap<Int> heap(_n);
2934  int * sj_arcs = new int[_n];
2935  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2936  if (_capacity[pointer] >0 && _flow[pointer] > 0) {
2937  heap.insert(_children[pointer],-_flow[pointer]);
2938  sj_arcs[_children[pointer]]=pointer;
2939  }
2940  }
2941  while (!heap.is_empty()) {
2942  Path<Int>* path = new Path<Int>();
2943  decomposition.push_back(path);
2944  Int& flow = path->flow_int;
2945  list_int& list = path->nodes;
2946  int node;
2947  heap.find_min(node,flow);
2948  heap.delete_min();
2949  flow=-flow; // max flow in fact
2950  Int init_flow=flow;
2951  int init_node=node;
2952  list_int pointers;
2953  pointers.push_back(sj_arcs[node]);
2954  while (node != t) {
2955  list.push_back(node);
2956  const int pr_begin=_pr_node[node];
2957  const int pr_end=_pr_node[node]+_num_arcs[node];
2958  int max_pointer=pr_begin;
2959  Int max_flow = 0;
2960  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2961  if (_capacity[pointer] >0 && _flow[pointer] > max_flow) {
2962  max_pointer=pointer;
2963  max_flow=_flow[pointer];
2964  }
2965  }
2966  flow=MIN(flow,max_flow);
2967  pointers.push_back(max_pointer);
2968  node=_children[max_pointer];
2969  }
2970  //stop();
2971  for (const_iterator_int it = pointers.begin(); it != pointers.end(); ++it) {
2972  _flow[*it]-=flow;
2973  _flow[_reverse[*it]]+=flow;
2974  }
2975  if (init_flow!=flow) {
2976  heap.insert(init_node,-init_flow+flow);
2977  }
2978  }
2979  delete[](sj_arcs);
2980 };
2981 
2982 template <typename Int>
2983 void MinCostFlow<Int>::print_dimacs(const char* name) const {
2984  ofstream stream;
2985  stream.open(name);
2986  stream << "p min " << _n << " " << _m << endl;
2987  for (int i = 0; i<_n; ++i) {
2988  if (_demand[i] != 0)
2989  stream << "n " << i+1 << " " << _demand[i] << endl;
2990  }
2991  for (int i = 0; i<_n; ++i) {
2992  const int pr_begin=_pr_node[i];
2993  const int pr_end=_pr_node[i]+_num_arcs[i];
2994  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
2995  if (_capacity[pointer] > 0) {
2996  stream << "a " << i+1 << " " << _children[pointer]+1 << " " << 0 << " " << _capacity[pointer] << " " << _cost[pointer] << endl;
2997  }
2998  }
2999  }
3000  stream.close();
3001 }
3002 
3003 template <typename Int>
3004 Int inline MinCostFlow<Int>::reduced_cost(const int node, const int child, const int pointer) const {
3005  return (_is_quadratic_cost && _quad_cost[pointer]) ? _cost[pointer]+_flow[pointer] + _prices[node]-_prices[child] :
3006  _cost[pointer] + _prices[node]-_prices[child];
3007 };
3008 
3010 template <typename Int>
3011 bool inline MinCostFlow<Int>::topological_sort(const bool admissible, bool* admiss_node, Int* reduced_costs) {
3012  const bool extern_admiss_node=admiss_node != NULL;
3013  const bool extern_reduced_costs=reduced_costs != NULL;
3014  int* indegree = new int[_n];
3015  for (int i = 0; i<_n; ++i) indegree[i]=0;
3016  if (admissible) {
3017  if (!extern_admiss_node)
3018  admiss_node=new bool[_maxm];
3019  for (int i = 0; i<_n; ++i) {
3020  const int pr_begin=_pr_node[i];
3021  const int pr_end=_pr_node[i]+_num_arcs[i];
3022  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
3023  const int child=_children[pointer];
3024  const int rcost=this->reduced_cost(i,child,pointer);
3025  if (extern_reduced_costs) reduced_costs[pointer]=rcost;
3026  admiss_node[pointer]=(_capacity[pointer] > _flow[pointer] && rcost < 0);
3027  if (admiss_node[pointer]) indegree[child]++;
3028  }
3029  }
3030  } else {
3031  for (int i = 0; i<_n; ++i) {
3032  const int pr_begin=_pr_node[i];
3033  const int pr_end=_pr_node[i]+_num_arcs[i];
3034  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
3035  if (_capacity[pointer] > 0)
3036  indegree[_children[pointer]]++;
3037  }
3038  }
3039  }
3040  list_int list;
3041  int next=0;
3042  for (int i = 0; i<_n; ++i) {
3043  if (indegree[i]==0) list.push_back(i);
3044  }
3045  while (!list.empty()) {
3046  int node=list.front();
3047  list.pop_front();
3048  _topological_order[next++]=node;
3049  if (admissible) {
3050  const int pr_begin=_pr_node[node];
3051  const int pr_end=_pr_node[node]+_num_arcs[node];
3052  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
3053  const int child=_children[pointer];
3054  if (admiss_node[pointer]) {
3055  indegree[child]--;
3056  if (!indegree[child]) list.push_back(child);
3057  }
3058  }
3059  } else {
3060  const int pr_begin=_pr_node[node];
3061  const int pr_end=_pr_node[node]+_num_arcs[node];
3062  for (int pointer = pr_begin; pointer<pr_end; ++pointer) {
3063  if (_capacity[pointer] > 0) {
3064  const int child=_children[pointer];
3065  indegree[child]--;
3066  if (!indegree[child]) list.push_back(child);
3067  }
3068  }
3069  }
3070  }
3071  //for (int i = next; i<_n; ++i) _topological_order[i]=-1;
3072 
3073  _topologically_sorted=!admissible; // if admissible, only the admissible graph is sorted
3074  delete[](indegree);
3075  if (!extern_admiss_node)
3076  delete[](admiss_node);
3077  return next==_n;
3078 };
3079 
3080 template <typename Int>
3081 void inline MinCostFlow<Int>::print_excess() const {
3082  cerr << "Excess: " << endl;
3083  for (int i= 0; i<_n; ++i) {
3084  cerr << _excess[i] << " ";
3085  }
3086  cerr << endl;
3087 };
3088 
3089 template <typename Int>
3090 void inline MinCostFlow<Int>::print_prices() const {
3091  cerr << "Prices: " << endl;
3092  for (int i= 0; i<_n; ++i) {
3093  cerr << _prices[i] << " ";
3094  }
3095  cerr << endl;
3096 };
3097 
3098 template <typename Int>
3099 void inline MinCostFlow<Int>::print_graph() const {
3100  cerr << "Graph: " << _n << " x " << _m << endl;
3101  for (int i= 0; i<_n; ++i) {
3102  cerr <<"***********************" << endl;
3103  cerr <<"Node: " << i << ", e(i): " << _excess[i] << ", pi(i): " << _prices[i] << ", d(i): " << _demand[i] << endl;
3104  const int pr=_pr_node[i];
3105  for (int j = 0; j<_num_arcs[i]; ++j) {
3106  cerr << " child: " << _children[pr+j] << ", cap: " << _capacity[pr+j] << ", cost: " << _cost[pr+j] << ", flow: " << _flow[pr+j] << endl;
3107  }
3108  }
3109  cerr << endl;
3110 };
3111 
3112 template <typename T = double, typename Int = long long> class GraphPath {
3113  public:
3114  GraphPath() { _n=0; _m=0; _min_cost_flow=NULL; };
3115  ~GraphPath() { delete(_min_cost_flow); };
3116 
3117  void init_graph(const GraphPathStruct<T>& graph);
3118  T eval_l0(const T* variables, List<Path<Int>*>* decomposition = NULL);
3119  T eval_conv(const T* variables, List<Path<Int>*>* decomposition = NULL);
3120  T eval_dual_norm(const T* variables, list_int* path_out = NULL);
3121  void proximal_l0(T* variables, const T lambda);
3122  void proximal_conv(T* variables,const T lambda);
3123  int n() const { return _n; };
3124 
3125  protected:
3126  void flow_decomposition(List<Path<Int>*>& decomposition) const;
3127  void scale_costs(const T lambda);
3128 
3129  private:
3130  int _n;
3131  int _m;
3133 
3134  Int _big_integer; // should be 64-bits max_precision
3135  // max demand for s should be big_integer
3136  // max capacity s-t idem
3137  Int _infinite_capacity; // should be _big_integer/n
3138  // unbounded max_capacity network infinite_capacity
3139  T _sf; // to convert input float data to integer
3140  T _maxsf; // to convert input float data to integer
3141  // sf*sf*(sum cost)*(sum demand) should be _big_integer ?
3145  // int* _indices;
3146 // int _num_fixed;
3148 };
3149 
3150 template <typename T, typename Int>
3152  //_indices=graph.indices;
3153 // _num_fixed=graph.num_fixed;
3154  _big_integer=std::numeric_limits<Int>::max();
3155  _n=graph.n;
3156  _m=graph.m;
3157  const int n2=_n*2+2;
3158  _infinite_capacity=_big_integer/n2;
3159  int* num_arcs=new int[n2];
3160  for (int i = 0; i<_n; ++i) {
3161  // s,t, j-j' j-j' dummy connexions
3162  num_arcs[i]= isinf(graph.start_weights[i]) ? 2 : 3;
3163  }
3164  for (int i = 0; i<_n; ++i) {
3165  num_arcs[i+_n]= isinf(graph.stop_weights[i]) ? 2 : 3;
3166  }
3167  num_arcs[n2-2]=_n+1; // s connexions
3168  num_arcs[n2-1]=_n+1; // t connexions
3169  for (int i = 0; i<_n; ++i) {
3170  for (int j = graph.jc[i]; j<graph.jc[i+1]; ++j) {
3171  num_arcs[i+_n]++;
3172  num_arcs[graph.ir[j]]++; // i'-j connexions
3173  }
3174  }
3175  _min_cost_flow=new MinCostFlow<Int>(n2,num_arcs);
3176 
3177  Vector<T> start_weights(graph.start_weights,_n);
3178  Vector<T> stop_weights(graph.stop_weights,_n);
3179  Vector<T> weights(graph.weights,_m);
3180  T max_weight=MAX(start_weights.fmaxval(),MAX(stop_weights.fmaxval(),weights.fmaxval()));
3181  _graphprecision=graph.precision;
3182 
3183  _sf=MIN(graph.precision,static_cast<T>(_big_integer)/(max_weight*1000000.0*n2));
3184  _init_weights=graph.weights;
3185  _init_start_weights=graph.start_weights;
3186  _init_stop_weights=graph.stop_weights;
3187  _min_cost_flow->add_edge(2*_n,2*_n+1,0,0,_big_integer); // s-t connexion
3188 
3189  // j-j' connexions
3190  for (int i = 0; i<_n; ++i) {
3191  _min_cost_flow->add_edge(i,i+_n,0,0,_infinite_capacity);
3192  _min_cost_flow->add_edge(i,i+_n,0,0,0); // dummy arc for piecewise linear costs
3193  }
3194  // s-j connexions
3195  for (int i = 0; i<_n; ++i) {
3196  if (!isinf(graph.start_weights[i])) {
3197  const Int cost=static_cast<Int>(ceil(graph.start_weights[i]*_sf));
3198  const double double_cost=static_cast<double>((graph.start_weights[i]));
3199  _min_cost_flow->add_edge(2*_n,i,cost,double_cost,_infinite_capacity);
3200  }
3201  }
3202  // j'-t connexions
3203  for (int i = 0; i<_n; ++i) {
3204  if (!isinf(graph.stop_weights[i])) {
3205  const Int cost=static_cast<Int>(ceil(graph.stop_weights[i]*_sf));
3206  const double double_cost=static_cast<double>((graph.stop_weights[i]));
3207  _min_cost_flow->add_edge(i+_n,2*_n+1,cost,double_cost,_infinite_capacity);
3208  }
3209  }
3210  // other connexions
3211  for (int i = 0; i<_n; ++i) {
3212  for (int j= graph.jc[i]; j<graph.jc[i+1]; ++j) {
3213  const Int cost=static_cast<Int>(ceil(graph.weights[j]*_sf));
3214  const double double_cost=static_cast<double>((graph.weights[j]));
3215  _min_cost_flow->add_edge(i+_n,graph.ir[j],cost,double_cost,_infinite_capacity);
3216  }
3217  }
3218  // s-t connexion
3219  _min_cost_flow->set_demand(2*_n,-_big_integer);
3220  _min_cost_flow->set_demand(2*_n+1,_big_integer);
3221  delete[](num_arcs);
3222 };
3223 
3224 template <typename T, typename Int>
3225 T GraphPath<T,Int>::eval_l0(const T* variables, List<Path<Int>*>* decomposition) {
3226  for (int i = 0; i<_n; ++i) {
3227  const Int dem= variables[i] ? static_cast<Int>(_sf) : 0;
3228  _min_cost_flow->set_demand(i,dem);
3229  _min_cost_flow->set_demand(i+_n,-dem);
3230  }
3231  _min_cost_flow->compute_min_cost(false,false);
3232  const T val = static_cast<T>(_min_cost_flow->compute_cost_double())/(2*_sf*_sf);
3233  if (decomposition) {
3234  for (int i = 0; i<_n; ++i) {
3235  const Int dem= variables[i] ? static_cast<Int>(_sf) : 0;
3236  _min_cost_flow->set_demand(i,0);
3237  _min_cost_flow->set_demand(i+_n,0);
3238  _min_cost_flow->add_flow(i,0,dem);
3239  }
3240  this->flow_decomposition(*decomposition);
3241  }
3242  // _min_cost_flow->print_graph();
3243  // _min_cost_flow->test_optimality_conditions();
3244  return val;
3245 };
3246 
3247 template <typename T, typename Int>
3248 T GraphPath<T,Int>::eval_conv(const T* variables, List<Path<Int>*>* decomposition) {
3249  for (int i = 0; i<_n; ++i) {
3250  const Int dem= static_cast<Int>(_sf*abs<T>(variables[i]));
3251  _min_cost_flow->set_demand(i,dem);
3252  _min_cost_flow->set_demand(i+_n,-dem);
3253  }
3254  _min_cost_flow->compute_min_cost(false,false);
3255  const T val = static_cast<T>(_min_cost_flow->compute_cost_double())/(2*_sf*_sf);
3256  if (decomposition) {
3257  for (int i = 0; i<_n; ++i) {
3258  const Int dem= static_cast<Int>(_sf*abs<T>(variables[i]));
3259  _min_cost_flow->set_demand(i,0);
3260  _min_cost_flow->set_demand(i+_n,0);
3261  _min_cost_flow->add_flow(i,0,dem);
3262  }
3263  this->flow_decomposition(*decomposition);
3264  }
3265  // _min_cost_flow->test_optimality_conditions();
3266  return val;
3267 };
3268 
3269 template <typename T, typename Int>
3270 T GraphPath<T,Int>::eval_dual_norm(const T* variables, list_int* path_out) {
3271  T tau=T(1.0);
3272  list_int path;
3273  bool exit_loop=false;
3274  bool first=true;
3275  _min_cost_flow->set_edge(2*_n,0,0,0);
3276 
3277  while (!exit_loop) {
3278  for (int i = 0; i<_n; ++i) {
3279  const Int fact= static_cast<Int>(_sf*abs<T>(variables[i]/tau));
3280  _min_cost_flow->set_edge(i,0,-fact,_infinite_capacity);
3281  _min_cost_flow->set_edge(i,1,0,0);
3282  }
3283  T delta=static_cast<T>(_min_cost_flow->cost_shortest_path_in_dag(path))/_sf;
3284  T gamma=0;
3285  for (const_iterator_int it = path.begin(); it != path.end(); ++it) {
3286  if (*it < _n) gamma+=abs<T>(variables[*it]);
3287  }
3288  T new_tau=gamma/(delta+gamma/tau);
3289  if (abs<T>(new_tau) < 1e-12 || abs<T>(delta) < 1e-12 || abs<T>(new_tau-tau) < 1e-12 || (!first && (new_tau <= tau))) exit_loop=true;
3290  tau=new_tau;
3291  first=false;
3292  }
3293 
3294  _min_cost_flow->set_edge(2*_n,0,0,_big_integer);
3295  for (int i = 0; i<_n; ++i) {
3296  _min_cost_flow->set_edge(i,0,0,_infinite_capacity);
3297  _min_cost_flow->set_edge(i,1,0,0);
3298  }
3299  if (path_out) {
3300  path_out->clear();
3301  path_out->fusion(path);
3302  }
3303  return tau;
3304 };
3305 
3306 template <typename T, typename Int>
3307 void GraphPath<T,Int>::proximal_l0(T* variables, const T lambda) {
3308  _min_cost_flow->save_costs();
3309  T oldsf=_sf;
3310  this->scale_costs(lambda);
3311  const Int unit= static_cast<Int>(_sf);
3312  for (int i = 0; i<2*_n; ++i) {
3313  _min_cost_flow->set_demand(i,0);
3314  }
3315  for (int i = 0; i<_n; ++i) {
3316  const Int fact= static_cast<Int>(_sf*(0.5*variables[i]*variables[i]));
3317  _min_cost_flow->set_edge(i,0,-fact,unit);
3318  _min_cost_flow->set_edge(i,1,0,_infinite_capacity);
3319  }
3320  _min_cost_flow->compute_min_cost(false,false);
3321 // _min_cost_flow->test_optimality_conditions();
3322 
3323  // _min_cost_flow->print_graph();
3324 
3325  for (int i = 0; i<_n; ++i) {
3327  variables[i]= _min_cost_flow->get_flow(i,0) > 0 ? variables[i] : 0;
3328  }
3329 
3330  for (int i = 0; i<_n; ++i) {
3331  _min_cost_flow->set_edge(i,0,0,_infinite_capacity);
3332  _min_cost_flow->set_edge(i,1,0,0);
3333  }
3334 
3335  _sf=oldsf;
3336  _min_cost_flow->restore_costs();
3337 // T new_loss=lambda*this->eval_l0(variables);
3338 // PRINT_F(init_loss)
3339 // PRINT_F(new_loss)
3340 // PRINT_F(diff+new_loss)
3341 // PRINT_F(diff2);
3342 // if (diff2 < diff+new_loss) {
3343 // PRINT_F(_sf)
3344 // stop();
3345 // }
3346 
3347 
3348 
3349 };
3350 
3351 template <typename T, typename Int>
3352 void GraphPath<T,Int>::proximal_conv(T* variables, const T lambda) {
3353  _min_cost_flow->set_is_quad_cost(true);
3354  _min_cost_flow->save_costs();
3355  T oldsf=_sf;
3356  this->scale_costs(lambda);
3357 // _min_cost_flow->scale_costs(static_cast<double>(lambda));
3358  for (int i = 0; i<2*_n; ++i) {
3359  _min_cost_flow->set_demand(i,0);
3360  }
3361  for (int i = 0; i<_n; ++i) {
3362  const Int fact= static_cast<Int>(_sf*(abs<T>(variables[i])));
3363  _min_cost_flow->set_edge(i,0,-fact,fact);
3364  _min_cost_flow->set_quad_cost(i,0,true);
3365  _min_cost_flow->set_edge(i,1,0,_infinite_capacity);
3366  }
3367  _min_cost_flow->compute_min_cost(false,false);
3368 // _min_cost_flow->test_optimality_conditions();
3369  for (int i = 0; i<_n; ++i) {
3370  variables[i]= variables[i] > 0 ? static_cast<T>(_min_cost_flow->get_flow(i,0))/_sf : -static_cast<T>(_min_cost_flow->get_flow(i,0))/_sf;
3371  }
3372  for (int i = 0; i<_n; ++i) {
3373  _min_cost_flow->set_edge(i,0,0,_infinite_capacity);
3374  _min_cost_flow->set_quad_cost(i,0,false);
3375  _min_cost_flow->set_edge(i,1,0,0);
3376  }
3377  _min_cost_flow->set_is_quad_cost(false);
3378  _min_cost_flow->restore_costs();
3379  _sf=oldsf;
3380 };
3381 
3382 template <typename T, typename Int>
3384  _min_cost_flow->set_edge(2*_n,0,0,0);
3385  _min_cost_flow->st_flow_decomposition_dag(decomposition,2*_n,2*_n+1);
3386  _min_cost_flow->set_edge(2*_n,0,0,_big_integer); // to prevent dummy s-t path
3387  for (ListIterator<Path<Int>*> it_path = decomposition.begin(); it_path != decomposition.end(); ++it_path) {
3388  list_int new_nodes;
3389  for (const_iterator_int it = it_path->nodes.begin(); it != it_path->nodes.end(); ++it) {
3390  if (*it <_n) new_nodes.push_back(*it);
3391  }
3392  it_path->nodes.clear();
3393  it_path->nodes.fusion(new_nodes);
3394  it_path->flow = static_cast<T>(it_path->flow_int)/_sf;
3395  }
3396 };
3397 
3398 template <typename T, typename Int>
3399 void GraphPath<T,Int>::scale_costs(const T lambda) {
3400  Vector<T> start_weights(_init_start_weights,_n);
3401  Vector<T> stop_weights(_init_stop_weights,_n);
3402  Vector<T> weights(_init_weights,_m);
3403  const int n2=_n*2+2;
3404  T max_weight=lambda*MAX(start_weights.fmaxval(),MAX(stop_weights.fmaxval(),weights.fmaxval()));
3405  _sf=MIN(_graphprecision,static_cast<T>(_big_integer)/(max_weight*1000000.0*n2));
3406 // cerr << "sf " << _sf << endl;
3407  _min_cost_flow->scale_costs(_sf*lambda);
3408 }
3409 
3410 }
3411 
3412 #endif
void set_capacity(const int node, const int num_arc, const Int cap)
Definition: project.h:2454
void proximal_conv(T *variables, const T lambda)
Definition: project.h:3352
Sparse Matrix class.
Definition: linalg.h:63
int * _labels
Definition: project.h:540
List< int > list_int
Definition: list.h:146
int * _pr_variables
Definition: project.h:145
void pop_front()
Definition: list.h:62
Definition: dag.h:26
int * N_own_variables
Definition: project.h:2245
void set_edge(const int node, const int num_arc, const Int cost, const Int cap)
Definition: project.h:2443
double compute_cost_double() const
Definition: project.h:2778
void init_split_variables(SpMatrix< T > &splitted_w, const int Ng, const int Nv)
Definition: project.h:780
int * _size_variables
Definition: project.h:144
void init_graph(const GraphPathStruct< T > &graph)
Definition: project.h:3151
T val_zero(const T *pr_alpha, const int current_node)
Definition: project.h:274
void proximal_l0(T *variables, const T lambda)
Definition: project.h:3307
bool check_flow()
Definition: project.h:835
T project_tree_l1(T *variables, const int n, const T lambda)
Definition: project.h:59
int pB(const int i) const
returns pB[i]
Definition: linalg.h:779
mwSize * gv_ir
Definition: project.h:2234
void copy(const Vector< T > &x)
make a copy of x
Definition: linalg.h:2865
T flow_component(const list_int &component, const int Ng)
Definition: project.h:1417
void set_weights(const T lambda)
Definition: project.h:889
list_int _list_active
Definition: project.h:2347
void perform_maxflow_component(const list_int &component)
Definition: project.h:1579
Int flow_int
Definition: project.h:2274
T dual_norm_inf(const Vector< T > &input, const Vector< T > &weights)
Definition: project.h:2033
Int reduced_cost(const int node, const int child, const int arc) const
Definition: project.h:3004
void inv(const Vector< T > &x)
A <- 1./x.
Definition: linalg.h:3103
void scale_costs(const T lambda)
Definition: project.h:3399
T eval_dual_norm(const T *variables, list_int *path_out=NULL)
Definition: project.h:3270
void stop()
stop the time
Definition: utils.h:149
void init_split_variables_aux(const int node, int &current_counter, Vector< int > &counter_node, list_int **splitted_w, const int Ng, const int Nv)
Definition: project.h:1114
void extractConnexComponents(std::list< list_int * > &connex_components)
Definition: project.h:1185
void proximal_operator(const T *variables_in, T *variables_out, const bool clever=false, const T *weights=NULL)
Definition: project.h:2105
T fmaxval() const
returns the maximum magnitude
Definition: linalg.h:2799
bool price_refine(const Int eps)
Definition: project.h:2801
int * _all_nodes
Definition: project.h:561
void print_labels()
Definition: project.h:762
void proj_zero(Vector< T > &input, const T fact=1.0)
Definition: project.h:395
T * _init_start_weights
Definition: project.h:3143
void component_relabelling(const list_int &component, const int max_label, const bool force)
Definition: project.h:1657
int * _num_edges
Definition: project.h:548
mwSize * groups_ir
Definition: project.h:2247
void print_excess() const
Definition: project.h:3081
MaxFlow(const int N, const int *num_edges, const int s, const int t)
Definition: project.h:565
void print_dimacs(const char *name) const
Definition: project.h:2983
void scale_flow(const T scal)
Definition: project.h:1907
T norm(const T *variables, T *work, const T *weights, const int Ng, const bool linf=true)
Definition: project.h:997
int * _order_dfs
Definition: project.h:149
void decrease_key(const int node, const T val)
Definition: list.h:171
int num_relabels
Definition: project.h:35
void st_flow_decomposition_dag(List< Path< Int > * > &list, const int s, const int t) const
Definition: project.h:2930
T * rawX() const
returns a modifiable reference of the data, DANGEROUS
Definition: linalg.h:593
int num_pushes
Definition: project.h:36
void sub_gradient(const Vector< T > &input, Vector< T > &output, const Vector< T > &weights, const int Ng)
Definition: project.h:979
MinCostFlow< Int > * _min_cost_flow
Definition: project.h:3132
T eval_conv(const T *variables, List< Path< Int > * > *decomposition=NULL)
Definition: project.h:3248
void restore_capacities()
Definition: project.h:1903
void flow_decomposition(List< Path< Int > * > &decomposition) const
Definition: project.h:3383
void scale_costs(const double scal)
Definition: project.h:2480
int * _reverse_address
Definition: project.h:553
bool empty() const
Definition: list.h:58
Int _infinite_capacity
Definition: project.h:3137
int num_global_relabels
Definition: project.h:37
void push_back(T elem)
Definition: list.h:69
void setn(const int n)
Definition: linalg.h:627
T * _copyexcess
Definition: project.h:542
void update_capacities(const list_int &component, T *work)
Definition: project.h:1742
bool cap_heuristic
Definition: project.h:41
void print_excess()
Definition: project.h:731
int mwSize
Definition: utils.h:38
Class Timer.
Definition: utils.h:138
const T & max(const T &a, const T &b)
Return the maximum between a and b.
Definition: utlCore.h:263
void scale_flow(const T scal)
Definition: project.h:882
T compute_thrs_project_l1(T *X, const int n, const T lambda)
Definition: project.h:1842
void save_flow()
Definition: project.h:814
T project_box(const list_int &component, const T *variables_in, T *variables_out, T *work, bool &fusion, const int Ng)
Definition: project.h:1301
void reset_component(const list_int &component)
Definition: project.h:1566
T project_weighted(const list_int &component, const T *variables_in, T *variables_out, T *work, const T *weights, const int Ng)
Definition: project.h:1217
static void stop()
a useful debugging function
Definition: misc.h:74
void print_graph() const
Definition: project.h:3099
T * _init_stop_weights
Definition: project.h:3144
ListIterator< T > & begin() const
Definition: list.h:117
int n() const
returns the size of the vector
Definition: linalg.h:591
bool compare_abs(T first, T second)
Definition: project.h:52
bool is_empty() const
Definition: list.h:154
void discharge(const list_int &component, const int u, const int max_label)
Definition: project.h:638
void print_sink()
Definition: project.h:904
bool gap_heuristic
Definition: project.h:40
void push_front(T elem)
Definition: list.h:80
#define MIN(a, b)
Definition: utils.h:47
T val_zero2(const T *pr_alpha, const int current_node, bool &tmp)
Definition: project.h:258
#define MAX(a, b)
Definition: utils.h:48
void save_capacities()
Definition: project.h:810
void setZeros()
Set all values to zero.
Definition: linalg.h:2871
T asum() const
computes the sum of the magnitudes of the vector
Definition: linalg.h:3324
Timer tglobal1
Definition: project.h:49
MaxFlow< T > * _maxflow
Definition: project.h:1928
T v(const int i) const
returns v[i]
Definition: linalg.h:783
void delete_min()
Definition: list.h:165
void set_is_quad_cost(const bool is_quad_cost)
Definition: project.h:2293
mwSize * gv_jc
Definition: project.h:2235
#define PRINT_I(name)
Definition: utils.h:54
T abs(const T x)
template version of the fabs function
void set_capacities_groups(const list_int &component, const Vector< T > &weights, const T lambda, const int Ng)
Definition: project.h:1805
T project(const list_int &component, const T *variables_in, T *variables_out, T *work, const int Ng)
Definition: project.h:1260
void create_tree(const int N_variables, int *own_variables, int *N_own_variables, T *lambda, mwSize *groups_ir, mwSize *groups_jc, const int N_groups, const int root_node=0)
Definition: project.h:184
#define EPSILON
Definition: utils.h:60
int perform_order(const int current_node, const int pointer)
Definition: project.h:206
void init_split_variables(SpMatrix< T > &splitted_w)
Definition: project.h:1919
void create_graph(const int Nv, const int Ng, T *weights, mwSize *var_ir, mwSize *var_jc)
Definition: project.h:1946
void save_flow()
Definition: project.h:1904
Dense Vector class.
Definition: linalg.h:65
T val_norm2(const T *pr_alpha, const int current_node, T &tmp, const bool l1=false)
Definition: project.h:238
bool _topologically_sorted
Definition: project.h:2345
int num_gap_relabels
Definition: project.h:38
void print_graph()
Definition: project.h:771
int * _children
Definition: project.h:552
double flow
Definition: project.h:2275
void price_update(const Int eps)
Definition: project.h:2597
void set_demand(const int node, const Int dem)
Definition: project.h:2285
Int get_flow(const int node, const int num_arc) const
Definition: project.h:2301
void insert(const int node, const T val)
Definition: list.h:157
int * _current_edges
Definition: project.h:547
void add_edge(const int u, const int v, const T cu, const T cv)
Definition: project.h:620
void proj_weighted_linf(Vector< T > &input, const Vector< T > &weights, const T fact=1.0)
Definition: project.h:315
bool splitComponent(const list_int &component, std::list< list_int * > &connex_components, const int Ng, bool *positive, const bool addpos=true)
Definition: project.h:1437
void perform_maxflow()
Definition: project.h:704
mwSize * _groups_jc
Definition: project.h:151
list_int nodes
Definition: project.h:2273
bool test_optimality_conditions() const
Definition: project.h:2746
T getMaxFlow() const
Definition: project.h:483
mwSize * gg_jc
Definition: project.h:2237
list_int ** _active_nodes
Definition: project.h:560
int * _pr_own_variables
Definition: project.h:147
void gap_relabelling(const list_int &component, const int gap, const int max_label)
Definition: project.h:1638
void start()
start the time
Definition: utils.h:146
void sub_grad(const Vector< T > &input, Vector< T > &output, const bool linf)
Definition: project.h:280
int * _pr_node
Definition: project.h:549
bool price_refine_heuristic
Definition: project.h:43
bool global_heuristic
Definition: project.h:39
void sub_gradient_aux(const Vector< T > &input, Vector< T > &output, const Vector< T > &weights, const int node, list_int &list, const int Ng)
Definition: project.h:941
Int cost_shortest_path_in_dag(list_int &path)
Definition: project.h:2894
void sub_gradient(const Vector< T > &input, Vector< T > &output, const Vector< T > &weights)
Definition: project.h:1916
void restore_flow()
Definition: project.h:821
void proj(Vector< T > &input, const bool l1=false, const T fact=1.0)
Definition: project.h:335
mwSize * groups_jc
Definition: project.h:2248
T dual_norm_inf(const Vector< T > &input)
Definition: project.h:421
int r(const int i) const
returns r[i]
Definition: linalg.h:781
void printElapsed()
print the elapsed time
Definition: utils.h:182
void print_component(const list_int &component)
Definition: project.h:918
void resize(const int m, const int n, const int nzmax)
resize the matrix
Definition: linalg.h:4221
int * own_variables
Definition: project.h:2244
void clear()
Definition: list.h:87
void discharge(const int node, const Int eps)
Definition: project.h:2680
void print_component2(const list_int &component)
Definition: project.h:1054
MinCostFlow(const int n, const int *max_num_arcs)
Definition: project.h:2355
void restore_flow()
Definition: project.h:1905
void set_quad_cost(const int node, const int num_arc, const bool quad_cost)
Definition: project.h:2289
mwSize * _groups_ir
Definition: project.h:150
#define EPSILON_MAXFLOW
Definition: project.h:26
void add_edge(const int u, const int v, const Int cost, const double double_cost, const Int cap)
Definition: project.h:2423
T front() const
Definition: list.h:59
bool * _active
Definition: project.h:544
void deactivate()
Definition: project.h:742
int * _order
Definition: project.h:148
void * end() const
Definition: list.h:118
double getElapsed() const
print the elapsed time
Definition: utils.h:193
void reset()
reset the timer
Definition: utils.h:155
bool _is_quadratic_cost
Definition: project.h:2348
bool * _seen
Definition: project.h:543
mwSize * gg_ir
Definition: project.h:2236
Timer tglobal3
Definition: project.h:49
int * _size_own_variables
Definition: project.h:146
void reset_flow()
Definition: project.h:875
void add_flow(const int node, const int num_arc, const Int flow)
Definition: project.h:2463
double * _init_double_cost
Definition: project.h:2341
int _N_variables
Definition: project.h:139
int * _topological_order
Definition: project.h:2344
void print()
Definition: project.h:1913
int _current_max_label
Definition: project.h:559
int perform_dfs(const int current_node, const int pointer)
Definition: project.h:220
int * _max_num_edges
Definition: project.h:546
T norm(const T *variables, T *work, const T *weights, const bool linf=true)
Definition: project.h:1914
void find_min(int &node, T &val) const
Definition: list.h:155
void fusion(const List< T > &list)
Definition: list.h:119
Int compute_cost() const
Definition: project.h:2765
T val_norm(const T *pr_alpha, const int current_node, const bool l1=false)
Definition: project.h:231
void restore_capacities()
Definition: project.h:830
void set_capacities_variables(const T *cap, const int Nv, const int Ng)
Definition: project.h:1796
void set_weights(const T lambda)
Definition: project.h:1908
T * _copycapacity
Definition: project.h:555
void global_relabelling()
Definition: project.h:1152
void set_weights(const T *weights, const T lambda)
Definition: project.h:1910
bool topological_sort(const bool admissible=false, bool *admiss=NULL, Int *rcosts=NULL)
the function assumes the graph is a DAG
Definition: project.h:3011
void print_prices() const
Definition: project.h:3090
int size() const
Definition: list.h:116
void restore_costs()
Definition: project.h:2475
T eval_l0(const T *variables, List< Path< Int > * > *decomposition=NULL)
Definition: project.h:3225
void compute_min_cost(const bool scale_data=true, const bool verbose=false)
Definition: project.h:2488
void setData(T *X, const int n)
Definition: linalg.h:607
Int refine(Int eps, const bool price_refine=false)
Definition: project.h:2542
int nzmax() const
Definition: project.h:530
void save_capacities()
Definition: project.h:1902
Int compute_uncap_cost() const
Definition: project.h:2792
void print_graph_aux(const int node)
Definition: project.h:1081
void reset_flow()
Definition: project.h:1906
void l1project_weighted(Vector< T > &out, const Vector< T > &weights, const T thrs, const bool residual=false) const
Definition: linalg.h:3417
#define INFINITY
Definition: utils.h:62
Timer tglobal2
Definition: project.h:49
T * _weights
Definition: project.h:1927
bool price_heuristic
Definition: project.h:42
int n() const
Definition: project.h:3123