gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Resolve several MSVC related compilation problems
0 3 0
default
3 files changed with 6 insertions and 1 deletions:
↑ Collapse diff ↑
Show white space 1536 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup demos
20 20
///\file
21 21
///\brief Demonstrating graph input and output
22 22
///
23 23
/// This simple demo program gives an example of how to read and write
24 24
/// a graph and additional maps (on the nodes or the edges) from/to a
25 25
/// stream. 
26 26
///
27 27
/// \include reader_writer_demo.cc
28 28

	
29 29
#include <iostream>
30 30
#include <lemon/smart_graph.h>
31 31
#include <lemon/lgf_reader.h>
32 32
#include <lemon/lgf_writer.h>
33 33
#include <lemon/random.h>
34 34

	
35 35

	
36 36
using namespace lemon;
37 37

	
38 38
int main(int argc, const char *argv[]) {
39 39
  const int n = argc > 1 ? std::atoi(argv[1]) : 20;
40
  const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * log(n));
40
  const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * std::log(double(n)));
41 41
  const int m = argc > 3 ? std::atoi(argv[3]) : 100;
42 42

	
43 43
  SmartDigraph digraph;
44 44

	
45 45
  std::stringstream ss;
46 46

	
47 47
  try {
48 48

	
49 49
    typedef SmartDigraph Digraph;
50 50
    typedef Digraph::Node Node;
51 51
    typedef Digraph::Arc Arc;
52 52
    typedef Digraph::ArcIt ArcIt;
53 53

	
54 54
    typedef Digraph::NodeMap<int> PotentialMap;
55 55
    typedef Digraph::ArcMap<int> CapacityMap;
56 56
    typedef Digraph::ArcMap<std::string> NameMap;
57 57

	
58 58
    Digraph digraph;
59 59
    PotentialMap potential(digraph);
60 60
    CapacityMap capacity(digraph);
61 61
    NameMap name(digraph);
62 62

	
63 63
    std::vector<Node> nodes;
64 64
    for (int i = 0; i < n; ++i) {
65 65
      Node node = digraph.addNode();
66 66
      potential[node] = rnd[m];
67 67
      nodes.push_back(node);
68 68
    }
69 69

	
70 70
    std::vector<Arc> arcs;
71 71
    for (int i = 0; i < e; ++i) {
72 72
      int s = rnd[n];
73 73
      int t = rnd[n];
74 74
      int c = rnd[m];
75 75
      Arc arc = digraph.addArc(nodes[s], nodes[t]);
76 76
      capacity[arc] = c;
77 77
      std::ostringstream os;
78 78
      os << "arc \t" << i << std::endl;
79 79
      name[arc] = os.str();
80 80
      arcs.push_back(arc);
81 81
    }
82 82

	
83 83

	
84 84
    DigraphWriter<Digraph>(ss, digraph).
85 85
      nodeMap("potential", potential).
86 86
      arcMap("capacity", capacity).
87 87
      arcMap("name", name).
88 88
      node("source", nodes[0]).
89 89
      node("target", nodes[1]).
90 90
      arc("bottleneck", arcs[e / 2]).
91 91
      attribute("creator", "lemon library").
92 92
      run();
93 93

	
94 94
  } catch (DataFormatError& error) {
95 95
    std::cerr << error.what() << std::endl;
96 96
  }
97 97

	
98 98
  try {
99 99

	
100 100
    typedef SmartDigraph Digraph;
101 101
    typedef Digraph::Node Node;
102 102
    typedef Digraph::Arc Arc;
103 103
    typedef Digraph::ArcIt ArcIt;
104 104

	
105 105
    typedef Digraph::NodeMap<int> LabelMap;
106 106
    typedef Digraph::NodeMap<int> PotentialMap;
107 107
    typedef Digraph::ArcMap<int> CapacityMap;
108 108
    typedef Digraph::ArcMap<std::string> NameMap;
109 109

	
110 110
    Digraph digraph;
111 111
    LabelMap label(digraph);
112 112
    PotentialMap potential(digraph);
113 113
    CapacityMap capacity(digraph);
114 114
    NameMap name(digraph);
115 115

	
116 116
    Node s, t;
117 117
    Arc a;
118 118
    
119 119
    std::string creator;
120 120

	
121 121
    for (int i = 0; i < n; ++i) {
122 122
      Node node = digraph.addNode();
123 123
      label[node] = i;
124 124
    }
125 125
    
126 126
    DigraphReader<Digraph>(ss, digraph).
127 127
      useNodes(label).
128 128
      nodeMap("potential", potential).
129 129
      arcMap("capacity", capacity).
130 130
      arcMap("name", name).
131 131
      node("source", s).
132 132
      node("target", t).
133 133
      arc("bottleneck", a).
134 134
      attribute("creator", creator).
135 135
      run();
136 136

	
137 137
    DigraphWriter<Digraph>(std::cout, digraph).
138 138
      nodeMap("potential", potential).
139 139
      arcMap("capacity", capacity).
140 140
      arcMap("name", name).
141 141
      node("source", s).
142 142
      node("target", t).
143 143
      arc("bottleneck", a).
144 144
      attribute("creator", creator).
145 145
      run();
146 146

	
147 147
  } catch (DataFormatError& error) {
148 148
    std::cerr << error.what() << std::endl;
149 149
  }
150 150

	
151 151

	
152 152
  return 0;
153 153
}
Show white space 1536 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_GRAPH_TO_EPS_H
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

	
22 22
#include<iostream>
23 23
#include<fstream>
24 24
#include<sstream>
25 25
#include<algorithm>
26 26
#include<vector>
27 27

	
28 28
#ifndef WIN32
29 29
#include<sys/time.h>
30 30
#include<ctime>
31 31
#else
32
#define WIN32_LEAN_AND_MEAN
33
#define NOMINMAX
32 34
#include<windows.h>
33 35
#endif
34 36

	
35 37
#include<lemon/math.h>
36 38
#include<lemon/bits/invalid.h>
37 39
#include<lemon/dim2.h>
38 40
#include<lemon/maps.h>
39 41
#include<lemon/color.h>
40 42
#include<lemon/bits/bezier.h>
41 43

	
42 44

	
43 45
///\ingroup eps_io
44 46
///\file
45 47
///\brief A well configurable tool for visualizing graphs
46 48

	
47 49
namespace lemon {
48 50

	
49 51
  namespace _graph_to_eps_bits {
50 52
    template<class MT>
51 53
    class _NegY {
52 54
    public:
53 55
      typedef typename MT::Key Key;
54 56
      typedef typename MT::Value Value;
55 57
      const MT &map;
56 58
      int yscale;
57 59
      _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
58 60
      Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
59 61
    };
60 62
  }
61 63
  
62 64
///Default traits class of \ref GraphToEps
63 65

	
64 66
///Default traits class of \ref GraphToEps
65 67
///
66 68
///\c G is the type of the underlying graph.
67 69
template<class G>
68 70
struct DefaultGraphToEpsTraits
69 71
{
70 72
  typedef G Graph;
71 73
  typedef typename Graph::Node Node;
72 74
  typedef typename Graph::NodeIt NodeIt;
73 75
  typedef typename Graph::Arc Arc;
74 76
  typedef typename Graph::ArcIt ArcIt;
75 77
  typedef typename Graph::InArcIt InArcIt;
76 78
  typedef typename Graph::OutArcIt OutArcIt;
77 79
  
78 80

	
79 81
  const Graph &g;
80 82

	
81 83
  std::ostream& os;
82 84
  
83 85
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
84 86
  CoordsMapType _coords;
85 87
  ConstMap<typename Graph::Node,double > _nodeSizes;
86 88
  ConstMap<typename Graph::Node,int > _nodeShapes;
87 89

	
88 90
  ConstMap<typename Graph::Node,Color > _nodeColors;
89 91
  ConstMap<typename Graph::Arc,Color > _arcColors;
90 92

	
91 93
  ConstMap<typename Graph::Arc,double > _arcWidths;
92 94

	
93 95
  double _arcWidthScale;
94 96
  
95 97
  double _nodeScale;
96 98
  double _xBorder, _yBorder;
97 99
  double _scale;
98 100
  double _nodeBorderQuotient;
99 101
  
100 102
  bool _drawArrows;
101 103
  double _arrowLength, _arrowWidth;
102 104
  
103 105
  bool _showNodes, _showArcs;
104 106

	
105 107
  bool _enableParallel;
106 108
  double _parArcDist;
107 109

	
108 110
  bool _showNodeText;
109 111
  ConstMap<typename Graph::Node,bool > _nodeTexts;  
110 112
  double _nodeTextSize;
111 113

	
112 114
  bool _showNodePsText;
113 115
  ConstMap<typename Graph::Node,bool > _nodePsTexts;  
114 116
  char *_nodePsTextsPreamble;
115 117
  
116 118
  bool _undirected;
117 119

	
118 120
  bool _pleaseRemoveOsStream;
119 121

	
120 122
  bool _scaleToA4;
121 123

	
122 124
  std::string _title;
123 125
  std::string _copyright;
124 126

	
125 127
  enum NodeTextColorType 
126 128
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
127 129
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
128 130

	
129 131
  bool _autoNodeScale;
130 132
  bool _autoArcWidthScale;
131 133

	
132 134
  bool _absoluteNodeSizes;
133 135
  bool _absoluteArcWidths;
134 136

	
135 137
  bool _negY;
136 138

	
137 139
  bool _preScale;
138 140
  ///Constructor
139 141

	
140 142
  ///Constructor
141 143
  ///\param _g is a reference to the graph to be printed
142 144
  ///\param _os is a reference to the output stream.
143 145
  ///\param _os is a reference to the output stream.
144 146
  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
145 147
  ///will be explicitly deallocated by the destructor.
146 148
  ///By default it is <tt>std::cout</tt>
147 149
  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
148 150
			  bool _pros=false) :
149 151
    g(_g), os(_os),
150 152
    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
151 153
    _nodeColors(WHITE), _arcColors(BLACK),
152 154
    _arcWidths(1.0), _arcWidthScale(0.003),
153 155
    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
154 156
    _nodeBorderQuotient(.1),
155 157
    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
156 158
    _showNodes(true), _showArcs(true),
157 159
    _enableParallel(false), _parArcDist(1),
158 160
    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
159 161
    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
160 162
    _undirected(lemon::UndirectedTagIndicator<G>::value),
161 163
    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
162 164
    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
163 165
    _autoNodeScale(false),
164 166
    _autoArcWidthScale(false),
165 167
    _absoluteNodeSizes(false),
166 168
    _absoluteArcWidths(false),
167 169
    _negY(false),
168 170
    _preScale(true)
169 171
  {}
170 172
};
171 173

	
172 174
///Auxiliary class to implement the named parameters of \ref graphToEps()
173 175

	
174 176
///Auxiliary class to implement the named parameters of \ref graphToEps()
175 177
template<class T> class GraphToEps : public T 
176 178
{
177 179
  // Can't believe it is required by the C++ standard
178 180
  using T::g;
179 181
  using T::os;
180 182

	
181 183
  using T::_coords;
182 184
  using T::_nodeSizes;
183 185
  using T::_nodeShapes;
184 186
  using T::_nodeColors;
185 187
  using T::_arcColors;
186 188
  using T::_arcWidths;
187 189

	
188 190
  using T::_arcWidthScale;
189 191
  using T::_nodeScale;
190 192
  using T::_xBorder;
191 193
  using T::_yBorder;
192 194
  using T::_scale;
193 195
  using T::_nodeBorderQuotient;
194 196
  
195 197
  using T::_drawArrows;
196 198
  using T::_arrowLength;
197 199
  using T::_arrowWidth;
198 200
  
199 201
  using T::_showNodes;
200 202
  using T::_showArcs;
201 203

	
202 204
  using T::_enableParallel;
203 205
  using T::_parArcDist;
204 206

	
205 207
  using T::_showNodeText;
206 208
  using T::_nodeTexts;  
207 209
  using T::_nodeTextSize;
208 210

	
209 211
  using T::_showNodePsText;
210 212
  using T::_nodePsTexts;  
211 213
  using T::_nodePsTextsPreamble;
212 214
  
213 215
  using T::_undirected;
214 216

	
215 217
  using T::_pleaseRemoveOsStream;
216 218

	
217 219
  using T::_scaleToA4;
218 220

	
219 221
  using T::_title;
220 222
  using T::_copyright;
221 223

	
222 224
  using T::NodeTextColorType;
223 225
  using T::CUST_COL;
224 226
  using T::DIST_COL;
225 227
  using T::DIST_BW;
226 228
  using T::_nodeTextColorType;
227 229
  using T::_nodeTextColors;
228 230

	
229 231
  using T::_autoNodeScale;
230 232
  using T::_autoArcWidthScale;
231 233

	
232 234
  using T::_absoluteNodeSizes;
233 235
  using T::_absoluteArcWidths;
234 236

	
235 237

	
236 238
  using T::_negY;
237 239
  using T::_preScale;
238 240

	
239 241
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
240 242

	
241 243
  typedef typename T::Graph Graph;
242 244
  typedef typename Graph::Node Node;
243 245
  typedef typename Graph::NodeIt NodeIt;
244 246
  typedef typename Graph::Arc Arc;
245 247
  typedef typename Graph::ArcIt ArcIt;
246 248
  typedef typename Graph::InArcIt InArcIt;
247 249
  typedef typename Graph::OutArcIt OutArcIt;
248 250

	
249 251
  static const int INTERPOL_PREC;
250 252
  static const double A4HEIGHT;
251 253
  static const double A4WIDTH;
252 254
  static const double A4BORDER;
253 255

	
254 256
  bool dontPrint;
255 257

	
256 258
public:
257 259
  ///Node shapes
258 260

	
259 261
  ///Node shapes
260 262
  ///
261 263
  enum NodeShapes { 
262 264
    /// = 0
263 265
    ///\image html nodeshape_0.png
264 266
    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
265 267
    CIRCLE=0, 
266 268
    /// = 1
267 269
    ///\image html nodeshape_1.png
268 270
    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
269 271
    ///
270 272
    SQUARE=1, 
271 273
    /// = 2
272 274
    ///\image html nodeshape_2.png
273 275
    ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
274 276
    ///
275 277
    DIAMOND=2,
276 278
    /// = 3
277 279
    ///\image html nodeshape_3.png
278 280
    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
279 281
    ///
280 282
    MALE=3,
281 283
    /// = 4
282 284
    ///\image html nodeshape_4.png
283 285
    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
284 286
    ///
285 287
    FEMALE=4
286 288
  };
287 289

	
288 290
private:
289 291
  class arcLess {
290 292
    const Graph &g;
291 293
  public:
292 294
    arcLess(const Graph &_g) : g(_g) {}
293 295
    bool operator()(Arc a,Arc b) const 
294 296
    {
295 297
      Node ai=std::min(g.source(a),g.target(a));
296 298
      Node aa=std::max(g.source(a),g.target(a));
297 299
      Node bi=std::min(g.source(b),g.target(b));
298 300
      Node ba=std::max(g.source(b),g.target(b));
299 301
      return ai<bi ||
300 302
	(ai==bi && (aa < ba || 
301 303
		    (aa==ba && ai==g.source(a) && bi==g.target(b))));
302 304
    }
303 305
  };
304 306
  bool isParallel(Arc e,Arc f) const
305 307
  {
306 308
    return (g.source(e)==g.source(f)&&
307 309
	    g.target(e)==g.target(f)) ||
308 310
      (g.source(e)==g.target(f)&&
309 311
       g.target(e)==g.source(f));
310 312
  }
311 313
  template<class TT>
312 314
  static std::string psOut(const dim2::Point<TT> &p) 
313 315
    {
314 316
      std::ostringstream os;	
315 317
      os << p.x << ' ' << p.y;
316 318
      return os.str();
317 319
    }
318 320
  static std::string psOut(const Color &c) 
319 321
    {
320 322
      std::ostringstream os;	
321 323
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
322 324
      return os.str();
323 325
    }
324 326
  
325 327
public:
326 328
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
327 329
  
328 330
  template<class X> struct CoordsTraits : public T {
329 331
  typedef X CoordsMapType;
330 332
    const X &_coords;
331 333
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
332 334
  };
333 335
  ///Sets the map of the node coordinates
334 336

	
335 337
  ///Sets the map of the node coordinates.
336 338
  ///\param x must be a node map with dim2::Point<double> or
337 339
  ///\ref dim2::Point "dim2::Point<int>" values. 
338 340
  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
339 341
    dontPrint=true;
340 342
    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
341 343
  }
342 344
  template<class X> struct NodeSizesTraits : public T {
343 345
    const X &_nodeSizes;
344 346
    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
345 347
  };
346 348
  ///Sets the map of the node sizes
347 349

	
348 350
  ///Sets the map of the node sizes
349 351
  ///\param x must be a node map with \c double (or convertible) values. 
350 352
  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
351 353
  {
352 354
    dontPrint=true;
353 355
    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
354 356
  }
355 357
  template<class X> struct NodeShapesTraits : public T {
356 358
    const X &_nodeShapes;
357 359
    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
358 360
  };
359 361
  ///Sets the map of the node shapes
360 362

	
361 363
  ///Sets the map of the node shapes.
362 364
  ///The available shape values
363 365
  ///can be found in \ref NodeShapes "enum NodeShapes".
364 366
  ///\param x must be a node map with \c int (or convertible) values. 
365 367
  ///\sa NodeShapes
366 368
  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
367 369
  {
368 370
    dontPrint=true;
369 371
    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
370 372
  }
371 373
  template<class X> struct NodeTextsTraits : public T {
372 374
    const X &_nodeTexts;
373 375
    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
374 376
  };
375 377
  ///Sets the text printed on the nodes
376 378

	
377 379
  ///Sets the text printed on the nodes
378 380
  ///\param x must be a node map with type that can be pushed to a standard
379 381
  ///ostream. 
380 382
  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
381 383
  {
382 384
    dontPrint=true;
383 385
    _showNodeText=true;
384 386
    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
385 387
  }
386 388
  template<class X> struct NodePsTextsTraits : public T {
387 389
    const X &_nodePsTexts;
388 390
    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
389 391
  };
390 392
  ///Inserts a PostScript block to the nodes
391 393

	
392 394
  ///With this command it is possible to insert a verbatim PostScript
393 395
  ///block to the nodes.
394 396
  ///The PS current point will be moved to the centre of the node before
395 397
  ///the PostScript block inserted.
396 398
  ///
397 399
  ///Before and after the block a newline character is inserted so you
398 400
  ///don't have to bother with the separators.
399 401
  ///
400 402
  ///\param x must be a node map with type that can be pushed to a standard
401 403
  ///ostream.
402 404
  ///
403 405
  ///\sa nodePsTextsPreamble()
404 406
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
405 407
  {
406 408
    dontPrint=true;
407 409
    _showNodePsText=true;
408 410
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
409 411
  }
410 412
  template<class X> struct ArcWidthsTraits : public T {
411 413
    const X &_arcWidths;
412 414
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
413 415
  };
414 416
  ///Sets the map of the arc widths
415 417

	
416 418
  ///Sets the map of the arc widths
417 419
  ///\param x must be a arc map with \c double (or convertible) values. 
418 420
  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
419 421
  {
420 422
    dontPrint=true;
421 423
    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
422 424
  }
423 425

	
424 426
  template<class X> struct NodeColorsTraits : public T {
425 427
    const X &_nodeColors;
426 428
    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
427 429
  };
428 430
  ///Sets the map of the node colors
429 431

	
430 432
  ///Sets the map of the node colors
431 433
  ///\param x must be a node map with \ref Color values.
432 434
  ///
433 435
  ///\sa Palette
434 436
  template<class X> GraphToEps<NodeColorsTraits<X> >
435 437
  nodeColors(const X &x)
436 438
  {
437 439
    dontPrint=true;
438 440
    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
439 441
  }
440 442
  template<class X> struct NodeTextColorsTraits : public T {
441 443
    const X &_nodeTextColors;
442 444
    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
443 445
  };
444 446
  ///Sets the map of the node text colors
445 447

	
446 448
  ///Sets the map of the node text colors
447 449
  ///\param x must be a node map with \ref Color values. 
448 450
  ///
449 451
  ///\sa Palette
450 452
  template<class X> GraphToEps<NodeTextColorsTraits<X> >
451 453
  nodeTextColors(const X &x)
452 454
  {
453 455
    dontPrint=true;
454 456
    _nodeTextColorType=CUST_COL;
455 457
    return GraphToEps<NodeTextColorsTraits<X> >
456 458
      (NodeTextColorsTraits<X>(*this,x));
457 459
  }
458 460
  template<class X> struct ArcColorsTraits : public T {
459 461
    const X &_arcColors;
460 462
    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
461 463
  };
462 464
  ///Sets the map of the arc colors
463 465

	
464 466
  ///Sets the map of the arc colors
465 467
  ///\param x must be a arc map with \ref Color values. 
466 468
  ///
467 469
  ///\sa Palette
468 470
  template<class X> GraphToEps<ArcColorsTraits<X> >
469 471
  arcColors(const X &x)
470 472
  {
471 473
    dontPrint=true;
472 474
    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
473 475
  }
474 476
  ///Sets a global scale factor for node sizes
475 477

	
476 478
  ///Sets a global scale factor for node sizes.
477 479
  /// 
478 480
  /// If nodeSizes() is not given, this function simply sets the node
479 481
  /// sizes to \c d.  If nodeSizes() is given, but
480 482
  /// autoNodeScale() is not, then the node size given by
481 483
  /// nodeSizes() will be multiplied by the value \c d.
482 484
  /// If both nodeSizes() and autoNodeScale() are used, then the
483 485
  /// node sizes will be scaled in such a way that the greatest size will be
484 486
  /// equal to \c d.
485 487
  /// \sa nodeSizes()
486 488
  /// \sa autoNodeScale()
487 489
  GraphToEps<T> &nodeScale(double d=.01) {_nodeScale=d;return *this;}
488 490
  ///Turns on/off the automatic node width scaling.
489 491

	
490 492
  ///Turns on/off the automatic node width scaling.
491 493
  ///
492 494
  ///\sa nodeScale()
493 495
  ///
494 496
  GraphToEps<T> &autoNodeScale(bool b=true) {
495 497
    _autoNodeScale=b;return *this;
496 498
  }
497 499

	
498 500
  ///Turns on/off the absolutematic node width scaling.
499 501

	
500 502
  ///Turns on/off the absolutematic node width scaling.
501 503
  ///
502 504
  ///\sa nodeScale()
503 505
  ///
504 506
  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
505 507
    _absoluteNodeSizes=b;return *this;
506 508
  }
507 509

	
508 510
  ///Negates the Y coordinates.
509 511

	
510 512
  ///Negates the Y coordinates.
511 513
  ///
512 514
  GraphToEps<T> &negateY(bool b=true) {
513 515
    _negY=b;return *this;
514 516
  }
515 517

	
516 518
  ///Turn on/off pre-scaling
517 519

	
518 520
  ///By default graphToEps() rescales the whole image in order to avoid
519 521
  ///very big or very small bounding boxes.
520 522
  ///
521 523
  ///This (p)rescaling can be turned off with this function.
522 524
  ///
523 525
  GraphToEps<T> &preScale(bool b=true) {
524 526
    _preScale=b;return *this;
525 527
  }
526 528

	
527 529
  ///Sets a global scale factor for arc widths
528 530

	
529 531
  /// Sets a global scale factor for arc widths.
530 532
  ///
531 533
  /// If arcWidths() is not given, this function simply sets the arc
532 534
  /// widths to \c d.  If arcWidths() is given, but
533 535
  /// autoArcWidthScale() is not, then the arc withs given by
534 536
  /// arcWidths() will be multiplied by the value \c d.
535 537
  /// If both arcWidths() and autoArcWidthScale() are used, then the
536 538
  /// arc withs will be scaled in such a way that the greatest width will be
537 539
  /// equal to \c d.
538 540
  GraphToEps<T> &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;}
539 541
  ///Turns on/off the automatic arc width scaling.
540 542

	
541 543
  ///Turns on/off the automatic arc width scaling.
542 544
  ///
543 545
  ///\sa arcWidthScale()
544 546
  ///
545 547
  GraphToEps<T> &autoArcWidthScale(bool b=true) {
546 548
    _autoArcWidthScale=b;return *this;
547 549
  }
548 550
  ///Turns on/off the absolutematic arc width scaling.
549 551

	
550 552
  ///Turns on/off the absolutematic arc width scaling.
551 553
  ///
552 554
  ///\sa arcWidthScale()
553 555
  ///
554 556
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
555 557
    _absoluteArcWidths=b;return *this;
556 558
  }
557 559
  ///Sets a global scale factor for the whole picture
558 560

	
559 561
  ///Sets a global scale factor for the whole picture
560 562
  ///
561 563

	
562 564
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
563 565
  ///Sets the width of the border around the picture
564 566

	
565 567
  ///Sets the width of the border around the picture
566 568
  ///
567 569
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
568 570
  ///Sets the width of the border around the picture
569 571

	
570 572
  ///Sets the width of the border around the picture
571 573
  ///
572 574
  GraphToEps<T> &border(double x, double y) {
573 575
    _xBorder=x;_yBorder=y;return *this;
574 576
  }
575 577
  ///Sets whether to draw arrows
576 578

	
577 579
  ///Sets whether to draw arrows
578 580
  ///
579 581
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
580 582
  ///Sets the length of the arrowheads
581 583

	
582 584
  ///Sets the length of the arrowheads
583 585
  ///
584 586
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
585 587
  ///Sets the width of the arrowheads
586 588

	
587 589
  ///Sets the width of the arrowheads
588 590
  ///
589 591
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
590 592
  
591 593
  ///Scales the drawing to fit to A4 page
592 594

	
593 595
  ///Scales the drawing to fit to A4 page
594 596
  ///
595 597
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
596 598
  
597 599
  ///Enables parallel arcs
598 600

	
599 601
  ///Enables parallel arcs
600 602
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
601 603
  
602 604
  ///Sets the distance 
603 605
  
604 606
  ///Sets the distance 
605 607
  ///
606 608
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
607 609
  
608 610
  ///Hides the arcs
609 611
  
610 612
  ///Hides the arcs
611 613
  ///
612 614
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
613 615
  ///Hides the nodes
614 616
  
615 617
  ///Hides the nodes
616 618
  ///
617 619
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
618 620
  
619 621
  ///Sets the size of the node texts
620 622
  
621 623
  ///Sets the size of the node texts
622 624
  ///
623 625
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
624 626

	
625 627
  ///Sets the color of the node texts to be different from the node color
626 628

	
627 629
  ///Sets the color of the node texts to be as different from the node color
628 630
  ///as it is possible
629 631
  ///
630 632
  GraphToEps<T> &distantColorNodeTexts()
631 633
  {_nodeTextColorType=DIST_COL;return *this;}
632 634
  ///Sets the color of the node texts to be black or white and always visible.
633 635

	
634 636
  ///Sets the color of the node texts to be black or white according to
635 637
  ///which is more 
636 638
  ///different from the node color
637 639
  ///
638 640
  GraphToEps<T> &distantBWNodeTexts()
639 641
  {_nodeTextColorType=DIST_BW;return *this;}
640 642

	
641 643
  ///Gives a preamble block for node Postscript block.
642 644
  
643 645
  ///Gives a preamble block for node Postscript block.
644 646
  ///
645 647
  ///\sa nodePsTexts()
646 648
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
647 649
    _nodePsTextsPreamble=str ;return *this;
648 650
  }
649 651
  ///Sets whether the the graph is undirected
650 652

	
651 653
  ///Sets whether the the graph is undirected.
652 654
  ///
653 655
  ///This setting is the default for undirected graphs.
654 656
  ///
655 657
  ///\sa directed()
656 658
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
657 659

	
658 660
  ///Sets whether the the graph is directed
659 661

	
660 662
  ///Sets whether the the graph is directed.
661 663
  ///Use it to show the edges as a pair of directed ones.
662 664
  ///
663 665
  ///This setting is the default for digraphs.
664 666
  ///
665 667
  ///\sa undirected()
666 668
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
667 669
  
668 670
  ///Sets the title.
669 671

	
670 672
  ///Sets the title of the generated image,
671 673
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
672 674
  ///the EPS file.
673 675
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
674 676
  ///Sets the copyright statement.
675 677

	
676 678
  ///Sets the copyright statement of the generated image,
677 679
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
678 680
  ///the EPS file.
679 681
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
680 682

	
681 683
protected:
682 684
  bool isInsideNode(dim2::Point<double> p, double r,int t) 
683 685
  {
684 686
    switch(t) {
685 687
    case CIRCLE:
686 688
    case MALE:
687 689
    case FEMALE:
688 690
      return p.normSquare()<=r*r;
689 691
    case SQUARE:
690 692
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
691 693
    case DIAMOND:
692 694
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
693 695
    }
694 696
    return false;
695 697
  }
696 698

	
697 699
public:
698 700
  ~GraphToEps() { }
699 701
  
700 702
  ///Draws the graph.
701 703

	
702 704
  ///Like other functions using
703 705
  ///\ref named-templ-func-param "named template parameters",
704 706
  ///this function calls the algorithm itself, i.e. in this case
705 707
  ///it draws the graph.
706 708
  void run() {
707 709
    //\todo better 'epsilon' would be nice here.
708 710
    const double EPSILON=1e-9;
709 711
    if(dontPrint) return;
710 712
    
711 713
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
712 714
      mycoords(_coords,_negY);
713 715

	
714 716
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
715 717
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
716 718
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
717 719
//        << "%%Copyright: XXXX\n"
718 720
    os << "%%Creator: LEMON, graphToEps()\n";
719 721

	
720 722
    {    
721 723
#ifndef WIN32 
722 724
      timeval tv;
723 725
      gettimeofday(&tv, 0);
724 726

	
725 727
      char cbuf[26];
726 728
      ctime_r(&tv.tv_sec,cbuf);
727 729
      os << "%%CreationDate: " << cbuf;
728 730
#else
729 731
      SYSTEMTIME time;
730 732
      char buf1[11], buf2[9], buf3[5];
731 733
      
732 734
      GetSystemTime(&time);
733 735
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
734 736
			"ddd MMM dd", buf1, 11) &&
735 737
	  GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time, 
736 738
			"HH':'mm':'ss", buf2, 9) &&
737 739
	  GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
738 740
				"yyyy", buf3, 5)) {
739 741
	os << "%%CreationDate: " << buf1 << ' ' 
740 742
	   << buf2 << ' ' << buf3 << std::endl;
741 743
      }	  
742 744
#endif
743 745
    }
744 746

	
745 747
    if (_autoArcWidthScale) {
746 748
      double max_w=0;
747 749
      for(ArcIt e(g);e!=INVALID;++e)
748 750
	max_w=std::max(double(_arcWidths[e]),max_w);
749 751
      ///\todo better 'epsilon' would be nice here.
750 752
      if(max_w>EPSILON) {
751 753
	_arcWidthScale/=max_w;
752 754
      }
753 755
    }
754 756

	
755 757
    if (_autoNodeScale) {
756 758
      double max_s=0;
757 759
      for(NodeIt n(g);n!=INVALID;++n)
758 760
	max_s=std::max(double(_nodeSizes[n]),max_s);
759 761
      ///\todo better 'epsilon' would be nice here.
760 762
      if(max_s>EPSILON) {
761 763
	_nodeScale/=max_s;
762 764
      }
763 765
    }
764 766

	
765 767
    double diag_len = 1;
766 768
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
767 769
      dim2::BoundingBox<double> bb;
768 770
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
769 771
      if (bb.empty()) {
770 772
	bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
771 773
      }
772 774
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
773 775
      if(diag_len<EPSILON) diag_len = 1;
774 776
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
775 777
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
776 778
    }
777 779
    
778 780
    dim2::BoundingBox<double> bb;
779 781
    for(NodeIt n(g);n!=INVALID;++n) {
780 782
      double ns=_nodeSizes[n]*_nodeScale;
781 783
      dim2::Point<double> p(ns,ns);
782 784
      switch(_nodeShapes[n]) {
783 785
      case CIRCLE:
784 786
      case SQUARE:
785 787
      case DIAMOND:
786 788
	bb.add(p+mycoords[n]);
787 789
	bb.add(-p+mycoords[n]);
788 790
	break;
789 791
      case MALE:
790 792
	bb.add(-p+mycoords[n]);
791 793
	bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
792 794
	break;
793 795
      case FEMALE:
794 796
	bb.add(p+mycoords[n]);
795 797
	bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
796 798
	break;
797 799
      }
798 800
    }
799 801
    if (bb.empty()) {
Show white space 1536 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_TIME_MEASURE_H
20 20
#define LEMON_TIME_MEASURE_H
21 21

	
22 22
///\ingroup timecount
23 23
///\file
24 24
///\brief Tools for measuring cpu usage
25 25

	
26 26
#ifdef WIN32
27
#define WIN32_LEAN_AND_MEAN
28
#define NOMINMAX
27 29
#include <windows.h>
28 30
#include <cmath>
29 31
#else
30 32
#include <sys/times.h>
31 33
#include <sys/time.h>
32 34
#endif
33 35

	
36
#include <string>
34 37
#include <fstream>
35 38
#include <iostream>
36 39

	
37 40
namespace lemon {
38 41

	
39 42
  /// \addtogroup timecount
40 43
  /// @{
41 44

	
42 45
  /// A class to store (cpu)time instances.
43 46

	
44 47
  /// This class stores five time values.
45 48
  /// - a real time
46 49
  /// - a user cpu time
47 50
  /// - a system cpu time
48 51
  /// - a user cpu time of children
49 52
  /// - a system cpu time of children
50 53
  ///
51 54
  /// TimeStamp's can be added to or substracted from each other and
52 55
  /// they can be pushed to a stream.
53 56
  ///
54 57
  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
55 58
  /// class is what you want to use instead.
56 59
  ///
57 60
  ///\author Alpar Juttner
58 61

	
59 62
  class TimeStamp
60 63
  {
61 64
    double utime;
62 65
    double stime;
63 66
    double cutime;
64 67
    double cstime;
65 68
    double rtime;
66 69
  
67 70
    void _reset() { 
68 71
      utime = stime = cutime = cstime = rtime = 0;
69 72
    }
70 73

	
71 74
  public:
72 75

	
73 76
    ///Read the current time values of the process
74 77
    void stamp()
75 78
    {
76 79
#ifndef WIN32
77 80
      timeval tv;
78 81
      gettimeofday(&tv, 0);
79 82
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
80 83

	
81 84
      tms ts;
82 85
      double tck=sysconf(_SC_CLK_TCK);
83 86
      times(&ts);
84 87
      utime=ts.tms_utime/tck;
85 88
      stime=ts.tms_stime/tck;
86 89
      cutime=ts.tms_cutime/tck;
87 90
      cstime=ts.tms_cstime/tck;
88 91
#else
89 92
      static const double ch = 4294967296.0e-7;
90 93
      static const double cl = 1.0e-7;
91 94

	
92 95
      FILETIME system;
93 96
      GetSystemTimeAsFileTime(&system);
94 97
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
95 98

	
96 99
      FILETIME create, exit, kernel, user;
97 100
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
98 101
	utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
99 102
	stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
100 103
	cutime = 0;
101 104
	cstime = 0;
102 105
      } else {
103 106
	rtime = 0;
104 107
	utime = 0;
105 108
	stime = 0;
106 109
	cutime = 0;
107 110
	cstime = 0;
108 111
      }
109 112
#endif      
110 113
    }
111 114
  
112 115
    /// Constructor initializing with zero
113 116
    TimeStamp()
114 117
    { _reset(); }
115 118
    ///Constructor initializing with the current time values of the process
116 119
    TimeStamp(void *) { stamp();}
117 120
  
118 121
    ///Set every time value to zero
119 122
    TimeStamp &reset() {_reset();return *this;}
120 123

	
121 124
    ///\e
122 125
    TimeStamp &operator+=(const TimeStamp &b)
123 126
    {
124 127
      utime+=b.utime;
125 128
      stime+=b.stime;
126 129
      cutime+=b.cutime;
127 130
      cstime+=b.cstime;
128 131
      rtime+=b.rtime;
129 132
      return *this;
130 133
    }
131 134
    ///\e
132 135
    TimeStamp operator+(const TimeStamp &b) const
133 136
    {
134 137
      TimeStamp t(*this);
135 138
      return t+=b;
136 139
    }
137 140
    ///\e
138 141
    TimeStamp &operator-=(const TimeStamp &b)
139 142
    {
140 143
      utime-=b.utime;
141 144
      stime-=b.stime;
142 145
      cutime-=b.cutime;
143 146
      cstime-=b.cstime;
144 147
      rtime-=b.rtime;
145 148
      return *this;
146 149
    }
147 150
    ///\e
148 151
    TimeStamp operator-(const TimeStamp &b) const
149 152
    {
150 153
      TimeStamp t(*this);
151 154
      return t-=b;
152 155
    }
153 156
    ///\e
154 157
    TimeStamp &operator*=(double b)
155 158
    {
156 159
      utime*=b;
157 160
      stime*=b;
158 161
      cutime*=b;
159 162
      cstime*=b;
160 163
      rtime*=b;
161 164
      return *this;
162 165
    }
163 166
    ///\e
164 167
    TimeStamp operator*(double b) const
165 168
    {
166 169
      TimeStamp t(*this);
167 170
      return t*=b;
168 171
    }
169 172
    friend TimeStamp operator*(double b,const TimeStamp &t);
170 173
    ///\e
171 174
    TimeStamp &operator/=(double b)
172 175
    {
173 176
      utime/=b;
174 177
      stime/=b;
175 178
      cutime/=b;
176 179
      cstime/=b;
177 180
      rtime/=b;
178 181
      return *this;
179 182
    }
180 183
    ///\e
181 184
    TimeStamp operator/(double b) const
182 185
    {
183 186
      TimeStamp t(*this);
184 187
      return t/=b;
185 188
    }
186 189
    ///The time ellapsed since the last call of stamp()
187 190
    TimeStamp ellapsed() const
188 191
    {
189 192
      TimeStamp t(NULL);
190 193
      return t-*this;
191 194
    }
192 195
  
193 196
    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
194 197
  
195 198
    ///Gives back the user time of the process
196 199
    double userTime() const
197 200
    {
198 201
      return utime;
199 202
    }
200 203
    ///Gives back the system time of the process
201 204
    double systemTime() const
202 205
    {
203 206
      return stime;
204 207
    }
205 208
    ///Gives back the user time of the process' children
206 209

	
207 210
    ///\note On <tt>WIN32</tt> platform this value is not calculated. 
208 211
    ///
209 212
    double cUserTime() const
210 213
    {
211 214
      return cutime;
212 215
    }
213 216
    ///Gives back the user time of the process' children
214 217

	
215 218
    ///\note On <tt>WIN32</tt> platform this value is not calculated. 
216 219
    ///
217 220
    double cSystemTime() const
218 221
    {
219 222
      return cstime;
220 223
    }
221 224
    ///Gives back the real time
222 225
    double realTime() const {return rtime;}
223 226
  };
224 227

	
225 228
  TimeStamp operator*(double b,const TimeStamp &t) 
226 229
  {
227 230
    return t*b;
228 231
  }
229 232
  
230 233
  ///Prints the time counters
231 234

	
232 235
  ///Prints the time counters in the following form:
233 236
  ///
234 237
  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
235 238
  ///
236 239
  /// where the values are the
237 240
  /// \li \c u: user cpu time,
238 241
  /// \li \c s: system cpu time,
239 242
  /// \li \c cu: user cpu time of children,
240 243
  /// \li \c cs: system cpu time of children,
241 244
  /// \li \c real: real time.
242 245
  /// \relates TimeStamp
243 246
  /// \note On <tt>WIN32</tt> platform the cummulative values are not
244 247
  /// calculated.
245 248
  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
246 249
  {
247 250
    os << "u: " << t.userTime() <<
248 251
      "s, s: " << t.systemTime() <<
249 252
      "s, cu: " << t.cUserTime() <<
250 253
      "s, cs: " << t.cSystemTime() <<
251 254
      "s, real: " << t.realTime() << "s";
252 255
    return os;
253 256
  }
254 257

	
255 258
  ///Class for measuring the cpu time and real time usage of the process
256 259

	
257 260
  ///Class for measuring the cpu time and real time usage of the process.
258 261
  ///It is quite easy-to-use, here is a short example.
259 262
  ///\code
260 263
  /// #include<lemon/time_measure.h>
261 264
  /// #include<iostream>
262 265
  ///
263 266
  /// int main()
264 267
  /// {
265 268
  ///
266 269
  ///   ...
267 270
  ///
268 271
  ///   Timer t;
269 272
  ///   doSomething();
270 273
  ///   std::cout << t << '\n';
271 274
  ///   t.restart();
272 275
  ///   doSomethingElse();
273 276
  ///   std::cout << t << '\n';
274 277
  ///
275 278
  ///   ...
276 279
  ///
277 280
  /// }
278 281
  ///\endcode
279 282
  ///
280 283
  ///The \ref Timer can also be \ref stop() "stopped" and
281 284
  ///\ref start() "started" again, so it is possible to compute collected
282 285
  ///running times.
283 286
  ///
284 287
  ///\warning Depending on the operation system and its actual configuration
285 288
  ///the time counters have a certain (10ms on a typical Linux system)
286 289
  ///granularity.
287 290
  ///Therefore this tool is not appropriate to measure very short times.
288 291
  ///Also, if you start and stop the timer very frequently, it could lead to
289 292
  ///distorted results.
290 293
  ///
291 294
  ///\note If you want to measure the running time of the execution of a certain
292 295
  ///function, consider the usage of \ref TimeReport instead.
293 296
  ///
294 297
  ///\todo This shouldn't be Unix (Linux) specific.
295 298
  ///\sa TimeReport
296 299
  ///
297 300
  ///\author Alpar Juttner
298 301
  class Timer
299 302
  {
300 303
    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
301 304
    TimeStamp start_time; //This is the relativ start-time if the timer
302 305
                          //is _running, the collected _running time otherwise.
303 306
    
304 307
    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
305 308
  
306 309
  public: 
307 310
    ///Constructor.
308 311

	
309 312
    ///\param run indicates whether or not the timer starts immediately.
310 313
    ///
311 314
    Timer(bool run=true) :_running(run) {_reset();}
312 315

	
313 316
    ///\name Control the state of the timer
314 317
    ///Basically a Timer can be either running or stopped,
315 318
    ///but it provides a bit finer control on the execution.
316 319
    ///The \ref Timer also counts the number of \ref start()
317 320
    ///executions, and is stops only after the same amount (or more)
318 321
    ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
319 322
    ///of recursive functions.
320 323
    ///
321 324

	
322 325
    ///@{
323 326

	
324 327
    ///Reset and stop the time counters
325 328

	
326 329
    ///This function resets and stops the time counters
327 330
    ///\sa restart()
328 331
    void reset()
329 332
    {
330 333
      _running=0;
331 334
      _reset();
332 335
    }
333 336

	
334 337
    ///Start the time counters
335 338
    
336 339
    ///This function starts the time counters.
337 340
    ///
338 341
    ///If the timer is started more than ones, it will remain running
339 342
    ///until the same amount of \ref stop() is called.
340 343
    ///\sa stop()
341 344
    void start() 
342 345
    {
343 346
      if(_running) _running++;
344 347
      else {
345 348
	_running=1;
346 349
	TimeStamp t;
347 350
	t.stamp();
348 351
	start_time=t-start_time;
349 352
      }
350 353
    }
351 354

	
352 355
    
353 356
    ///Stop the time counters
354 357

	
355 358
    ///This function stops the time counters. If start() was executed more than
356 359
    ///once, then the same number of stop() execution is necessary the really
357 360
    ///stop the timer.
358 361
    /// 
359 362
    ///\sa halt()
360 363
    ///\sa start()
361 364
    ///\sa restart()
362 365
    ///\sa reset()
363 366

	
364 367
    void stop() 
365 368
    {
366 369
      if(_running && !--_running) {
367 370
	TimeStamp t;
368 371
	t.stamp();
369 372
	start_time=t-start_time;
370 373
      }
371 374
    }
372 375

	
373 376
    ///Halt (i.e stop immediately) the time counters
374 377

	
375 378
    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
376 379
    ///is a faster
377 380
    ///equivalent of the following.
378 381
    ///\code
379 382
    ///  while(t.running()) t.stop()
380 383
    ///\endcode
381 384
    ///
382 385
    ///
383 386
    ///\sa stop()
384 387
    ///\sa restart()
385 388
    ///\sa reset()
386 389

	
387 390
    void halt() 
388 391
    {
389 392
      if(_running) {
390 393
	_running=0;
391 394
	TimeStamp t;
392 395
	t.stamp();
393 396
	start_time=t-start_time;
394 397
      }
395 398
    }
396 399

	
397 400
    ///Returns the running state of the timer
398 401

	
399 402
    ///This function returns the number of stop() exections that is
400 403
    ///necessary to really stop the timer.
401 404
    ///For example the timer
402 405
    ///is running if and only if the return value is \c true
403 406
    ///(i.e. greater than
404 407
    ///zero).
405 408
    int running()  { return _running; }
406 409
    
407 410
    
408 411
    ///Restart the time counters
409 412

	
410 413
    ///This function is a shorthand for
411 414
    ///a reset() and a start() calls.
412 415
    ///
413 416
    void restart() 
414 417
    {
415 418
      reset();
416 419
      start();
417 420
    }
418 421
    
419 422
    ///@}
420 423

	
421 424
    ///\name Query Functions for the ellapsed time
422 425

	
423 426
    ///@{
424 427

	
425 428
    ///Gives back the ellapsed user time of the process
426 429
    double userTime() const
427 430
    {
428 431
      return operator TimeStamp().userTime();
429 432
    }
430 433
    ///Gives back the ellapsed system time of the process
431 434
    double systemTime() const
432 435
    {
433 436
      return operator TimeStamp().systemTime();
434 437
    }
435 438
    ///Gives back the ellapsed user time of the process' children
436 439

	
437 440
    ///\note On <tt>WIN32</tt> platform this value is not calculated. 
438 441
    ///
439 442
    double cUserTime() const
440 443
    {
441 444
      return operator TimeStamp().cUserTime();
442 445
    }
443 446
    ///Gives back the ellapsed user time of the process' children
444 447

	
445 448
    ///\note On <tt>WIN32</tt> platform this value is not calculated. 
446 449
    ///
447 450
    double cSystemTime() const
448 451
    {
449 452
      return operator TimeStamp().cSystemTime();
450 453
    }
451 454
    ///Gives back the ellapsed real time
452 455
    double realTime() const
453 456
    {
454 457
      return operator TimeStamp().realTime();
455 458
    }
456 459
    ///Computes the ellapsed time
457 460

	
458 461
    ///This conversion computes the ellapsed time, therefore you can print
459 462
    ///the ellapsed time like this.
460 463
    ///\code
461 464
    ///  Timer t;
462 465
    ///  doSomething();
463 466
    ///  std::cout << t << '\n';
464 467
    ///\endcode
465 468
    operator TimeStamp () const
466 469
    {
467 470
      TimeStamp t;
468 471
      t.stamp();
469 472
      return _running?t-start_time:start_time;
470 473
    }
471 474

	
472 475

	
473 476
    ///@}
474 477
  };
475 478

	
476 479
  ///Same as \ref Timer but prints a report on destruction.
477 480

	
478 481
  ///Same as \ref Timer but prints a report on destruction.
479 482
  ///This example shows its usage.
480 483
  ///\code
481 484
  ///  void myAlg(ListGraph &g,int n)
482 485
  ///  {
483 486
  ///    TimeReport tr("Running time of myAlg: ");
484 487
  ///    ... //Here comes the algorithm
485 488
  ///  }
486 489
  ///\endcode
487 490
  ///
488 491
  ///\sa Timer
489 492
  ///\sa NoTimeReport
490 493
  ///\todo There is no test case for this
491 494
  class TimeReport : public Timer 
492 495
  {
493 496
    std::string _title;
494 497
    std::ostream &_os;
495 498
  public:
496 499
    ///\e
497 500

	
498 501
    ///\param title This text will be printed before the ellapsed time.
499 502
    ///\param os The stream to print the report to.
500 503
    ///\param run Sets whether the timer should start immediately.
501 504

	
502 505
    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
503 506
      : Timer(run), _title(title), _os(os){}
504 507
    ///\e Prints the ellapsed time on destruction.
505 508
    ~TimeReport() 
506 509
    {
507 510
      _os << _title << *this << std::endl;
508 511
    }
509 512
  };
510 513
      
511 514
  ///'Do nothing' version of \ref TimeReport
512 515

	
513 516
  ///\sa TimeReport
514 517
  ///
515 518
  class NoTimeReport
516 519
  {
517 520
  public:
518 521
    ///\e
519 522
    NoTimeReport(std::string,std::ostream &,bool) {}
520 523
    ///\e
521 524
    NoTimeReport(std::string,std::ostream &) {}
522 525
    ///\e
523 526
    NoTimeReport(std::string) {}
524 527
    ///\e Do nothing.
525 528
    ~NoTimeReport() {}
526 529

	
527 530
    operator TimeStamp () const { return TimeStamp(); }
528 531
    void reset() {}
529 532
    void start() {}
530 533
    void stop() {}
531 534
    void halt() {} 
532 535
    int running() { return 0; }
533 536
    void restart() {}
534 537
    double userTime() const { return 0; }
535 538
    double systemTime() const { return 0; }
536 539
    double cUserTime() const { return 0; }
537 540
    double cSystemTime() const { return 0; }
538 541
    double realTime() const { return 0; }
539 542
  };
540 543
      
541 544
  ///Tool to measure the running time more exactly.
542 545
  
543 546
  ///This function calls \c f several times and returns the average
544 547
  ///running time. The number of the executions will be choosen in such a way
545 548
  ///that the full real running time will be roughly between \c min_time
546 549
  ///and <tt>2*min_time</tt>.
547 550
  ///\param f the function object to be measured.
548 551
  ///\param min_time the minimum total running time.
549 552
  ///\retval num if it is not \c NULL, then the actual
550 553
  ///        number of execution of \c f will be written into <tt>*num</tt>.
551 554
  ///\retval full_time if it is not \c NULL, then the actual
552 555
  ///        total running time will be written into <tt>*full_time</tt>.
553 556
  ///\return The average running time of \c f.
554 557
  
555 558
  template<class F>
556 559
  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
557 560
                            TimeStamp *full_time=NULL)
558 561
  {
559 562
    TimeStamp full;
560 563
    unsigned int total=0;
561 564
    Timer t;
562 565
    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
563 566
      for(;total<tn;total++) f();
564 567
      full=t;
565 568
    }
566 569
    if(num) *num=total;
567 570
    if(full_time) *full_time=full;
568 571
    return full/total;
569 572
  }
570 573
  
571 574
  /// @}  
572 575

	
573 576

	
574 577
} //namespace lemon
575 578

	
576 579
#endif //LEMON_TIME_MEASURE_H
0 comments (0 inline)