lemon/matrix_maps.h
author klao
Thu, 16 Mar 2006 13:52:12 +0000
changeset 2009 de287863cc98
parent 1993 2115143eceea
child 2039 dacc4ce9474d
permissions -rw-r--r--
rethrow fix
deba@1720
     1
/* -*- C++ -*-
deba@1720
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1720
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1720
     8
 *
deba@1720
     9
 * Permission to use, modify and distribute this software is granted
deba@1720
    10
 * provided that this copyright notice appears in all copies. For
deba@1720
    11
 * precise terms see the accompanying LICENSE file.
deba@1720
    12
 *
deba@1720
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1720
    14
 * express or implied, and with no claim as to its suitability for any
deba@1720
    15
 * purpose.
deba@1720
    16
 *
deba@1720
    17
 */
deba@1720
    18
deba@1720
    19
#ifndef LEMON_MATRIX_MAPS_H
deba@1720
    20
#define LEMON_MATRIX_MAPS_H
deba@1720
    21
deba@1720
    22
deba@1720
    23
#include <vector>
deba@1993
    24
#include <lemon/bits/utility.h>
deba@1720
    25
#include <lemon/maps.h>
deba@1720
    26
deba@1720
    27
deba@1720
    28
/// \file
deba@1720
    29
/// \ingroup maps
deba@1720
    30
/// \brief Maps indexed with pairs of items.
deba@1720
    31
///
deba@1720
    32
/// \todo This file has the same name as the concept file in concept/,
deba@1720
    33
///  and this is not easily detectable in docs...
deba@1720
    34
namespace lemon {
deba@1720
    35
deba@1720
    36
  /// \brief Map for the coloumn view of the matrix
deba@1720
    37
  ///
deba@1720
    38
  /// Map for the coloumn view of the matrix.
deba@1720
    39
  template <typename _MatrixMap>
deba@1751
    40
  class MatrixRowMap : public MapTraits<_MatrixMap> {
deba@1720
    41
  public:
deba@1720
    42
    typedef _MatrixMap MatrixMap;
deba@1720
    43
    typedef typename MatrixMap::SecondKey Key;
deba@1720
    44
    typedef typename MatrixMap::Value Value;
deba@1720
    45
deba@1720
    46
deba@1751
    47
    MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row) 
deba@1720
    48
      : matrix(_matrix), row(_row) {}
deba@1720
    49
deba@1720
    50
    /// \brief Subscription operator
deba@1720
    51
    ///
deba@1720
    52
    /// Subscription operator.
deba@1720
    53
    typename MapTraits<MatrixMap>::ReturnValue
deba@1720
    54
    operator[](Key col) {
deba@1751
    55
      return matrix(row, col);
deba@1720
    56
    }
deba@1720
    57
deba@1720
    58
    /// \brief Setter function
deba@1720
    59
    ///
deba@1720
    60
    /// Setter function.
deba@1720
    61
    void set(Key col, const Value& val) {
deba@1751
    62
      matrix.set(row, col, val);
deba@1720
    63
    }
deba@1720
    64
      
deba@1720
    65
    /// \brief Subscription operator
deba@1720
    66
    ///
deba@1720
    67
    /// Subscription operator.
deba@1720
    68
    typename MapTraits<MatrixMap>::ConstReturnValue
deba@1720
    69
    operator[](Key col) const {
deba@1751
    70
      return matrix(row, col);
deba@1720
    71
    }
deba@1720
    72
deba@1720
    73
  private:
deba@1720
    74
    MatrixMap& matrix;
deba@1751
    75
    typename MatrixMap::FirstKey row;
deba@1720
    76
  };
deba@1720
    77
deba@1720
    78
  /// \brief Map for the row view of the matrix
deba@1720
    79
  ///
deba@1720
    80
  /// Map for the row view of the matrix.
deba@1720
    81
  template <typename _MatrixMap>
deba@1720
    82
  class ConstMatrixRowMap : public MapTraits<_MatrixMap> {
deba@1720
    83
  public:
deba@1720
    84
    typedef _MatrixMap MatrixMap;
deba@1751
    85
    typedef typename MatrixMap::SecondKey Key;
deba@1720
    86
    typedef typename MatrixMap::Value Value;
deba@1720
    87
deba@1751
    88
deba@1720
    89
    ConstMatrixRowMap(const MatrixMap& _matrix, 
deba@1751
    90
		      typename MatrixMap::FirstKey _row) 
deba@1720
    91
      : matrix(_matrix), row(_row) {}
deba@1720
    92
deba@1720
    93
    /// \brief Subscription operator
deba@1720
    94
    ///
deba@1720
    95
    /// Subscription operator.
deba@1720
    96
    typename MapTraits<MatrixMap>::ConstReturnValue
deba@1720
    97
    operator[](Key col) const {
deba@1751
    98
      return matrix(row, col);
deba@1720
    99
    }
deba@1720
   100
deba@1720
   101
  private:
deba@1720
   102
    const MatrixMap& matrix;
deba@1751
   103
    typename MatrixMap::FirstKey row;
deba@1720
   104
  };
deba@1720
   105
deba@1720
   106
  /// \brief Gives back a row view of the matrix map
deba@1720
   107
  ///
deba@1720
   108
  /// Gives back a row view of the matrix map.
deba@1720
   109
  template <typename MatrixMap>
deba@1720
   110
  MatrixRowMap<MatrixMap> matrixRowMap(MatrixMap& matrixMap,
deba@1751
   111
				       typename MatrixMap::FirstKey row) {
deba@1720
   112
    return MatrixRowMap<MatrixMap>(matrixMap, row);
deba@1720
   113
  }
deba@1720
   114
deba@1720
   115
  template <typename MatrixMap>
deba@1751
   116
  ConstMatrixRowMap<MatrixMap>
deba@1751
   117
  matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) {
deba@1720
   118
    return ConstMatrixRowMap<MatrixMap>(matrixMap, row);
deba@1720
   119
  }
deba@1720
   120
deba@1751
   121
  /// \brief Map for the row view of the matrix
deba@1751
   122
  ///
deba@1751
   123
  /// Map for the row view of the matrix.
deba@1751
   124
  template <typename _MatrixMap>
deba@1751
   125
  class MatrixColMap : public MapTraits<_MatrixMap> {
deba@1751
   126
  public:
deba@1751
   127
    typedef _MatrixMap MatrixMap;
deba@1751
   128
    typedef typename MatrixMap::FirstKey Key;
deba@1751
   129
    typedef typename MatrixMap::Value Value;
deba@1751
   130
deba@1751
   131
    MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col) 
deba@1751
   132
      : matrix(_matrix), col(_col) {}
deba@1751
   133
deba@1751
   134
    /// \brief Subscription operator
deba@1751
   135
    ///
deba@1751
   136
    /// Subscription operator.
deba@1751
   137
    typename MapTraits<MatrixMap>::ReturnValue
deba@1751
   138
    operator[](Key row) {
deba@1751
   139
      return matrix(row, col);
deba@1751
   140
    }
deba@1751
   141
deba@1751
   142
    /// \brief Setter function
deba@1751
   143
    ///
deba@1751
   144
    /// Setter function.
deba@1751
   145
    void set(Key row, const Value& val) {
deba@1751
   146
      matrix.set(row, col, val);
deba@1751
   147
    }
deba@1751
   148
      
deba@1751
   149
    /// \brief Subscription operator
deba@1751
   150
    ///
deba@1751
   151
    /// Subscription operator.
deba@1751
   152
    typename MapTraits<MatrixMap>::ConstReturnValue
deba@1751
   153
    operator[](Key row) const {
deba@1751
   154
      return matrix(row, col);
deba@1751
   155
    }
deba@1751
   156
deba@1751
   157
  private:
deba@1751
   158
    MatrixMap& matrix;
deba@1751
   159
    typename MatrixMap::SecondKey col;
deba@1751
   160
  };
deba@1751
   161
deba@1751
   162
  /// \brief Map for the col view of the matrix
deba@1751
   163
  ///
deba@1751
   164
  /// Map for the col view of the matrix.
deba@1751
   165
  template <typename _MatrixMap>
deba@1751
   166
  class ConstMatrixColMap : public MapTraits<_MatrixMap> {
deba@1751
   167
  public:
deba@1751
   168
    typedef _MatrixMap MatrixMap;
deba@1751
   169
    typedef typename MatrixMap::FirstKey Key;
deba@1751
   170
    typedef typename MatrixMap::Value Value;
deba@1751
   171
deba@1751
   172
    ConstMatrixColMap(const MatrixMap& _matrix, 
deba@1751
   173
		      typename MatrixMap::SecondKey _col) 
deba@1751
   174
      : matrix(_matrix), col(_col) {}
deba@1751
   175
deba@1751
   176
    /// \brief Subscription operator
deba@1751
   177
    ///
deba@1751
   178
    /// Subscription operator.
deba@1751
   179
    typename MapTraits<MatrixMap>::ConstReturnValue
deba@1751
   180
    operator[](Key row) const {
deba@1751
   181
      return matrix(row, col);
deba@1751
   182
    }
deba@1751
   183
deba@1751
   184
  private:
deba@1751
   185
    const MatrixMap& matrix;
deba@1751
   186
    typename MatrixMap::SecondKey col;
deba@1751
   187
  };
deba@1751
   188
deba@1751
   189
  /// \brief Gives back a col view of the matrix map
deba@1751
   190
  ///
deba@1751
   191
  /// Gives back a col view of the matrix map.
deba@1751
   192
  template <typename MatrixMap>
deba@1751
   193
  MatrixColMap<MatrixMap> matrixColMap(MatrixMap& matrixMap,
deba@1751
   194
				       typename MatrixMap::SecondKey col) {
deba@1751
   195
    return MatrixColMap<MatrixMap>(matrixMap, col);
deba@1751
   196
  }
deba@1751
   197
deba@1751
   198
  template <typename MatrixMap>
deba@1751
   199
  ConstMatrixColMap<MatrixMap> 
deba@1751
   200
  matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) {
deba@1751
   201
    return ConstMatrixColMap<MatrixMap>(matrixMap, col);
deba@1751
   202
  }
deba@1751
   203
deba@1720
   204
  /// \brief Container for store values for each ordered pair of graph items
deba@1720
   205
  ///
alpar@1757
   206
  /// This data structure can strore for each pair of the same item
deba@1720
   207
  /// type a value. It increase the size of the container when the 
deba@1720
   208
  /// associated graph modified, so it updated automaticly whenever
deba@1720
   209
  /// it is needed.
deba@1720
   210
  template <typename _Graph, typename _Item, typename _Value>
deba@1720
   211
  class DynamicMatrixMap 
deba@1999
   212
    : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
deba@1720
   213
  public:
deba@1999
   214
    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase 
deba@1999
   215
    Parent;
deba@1720
   216
deba@1720
   217
    typedef _Graph Graph;
deba@1720
   218
    typedef _Item Key;
deba@1720
   219
deba@1720
   220
    typedef _Item FirstKey;
deba@1720
   221
    typedef _Item SecondKey;
deba@1720
   222
    typedef _Value Value;
deba@1720
   223
deba@1720
   224
    typedef True ReferenceMapTag;
deba@1720
   225
deba@1720
   226
  private:
deba@1720
   227
		
deba@1720
   228
    typedef std::vector<Value> Container;
deba@1720
   229
deba@1720
   230
  public:
deba@1720
   231
deba@1720
   232
    typedef typename Container::reference Reference;
deba@1720
   233
    typedef typename Container::const_reference ConstReference;
deba@1720
   234
deba@1720
   235
    /// \brief Creates an item matrix for the given graph
deba@1720
   236
    ///
deba@1720
   237
    /// Creates an item matrix for the given graph.
deba@1720
   238
    DynamicMatrixMap(const Graph& _graph) 
deba@1999
   239
      : values(size(_graph.maxId(Key()) + 1)) {
deba@1999
   240
      Parent::attach(_graph.getNotifier(Key()));
deba@1720
   241
    }
deba@1720
   242
deba@1720
   243
    /// \brief Creates an item matrix for the given graph
deba@1720
   244
    ///
deba@1720
   245
    /// Creates an item matrix for the given graph and assigns for each
deba@1720
   246
    /// pairs of keys the given parameter.
deba@1720
   247
    DynamicMatrixMap(const Graph& _graph, const Value& _val) 
deba@1999
   248
      : values(size(_graph.maxId(Key()) + 1), _val) {
deba@1999
   249
      Parent::attach(_graph.getNotifier(Key()));
deba@1720
   250
    }
deba@1720
   251
deba@1720
   252
    /// \brief Gives back the value assigned to the \c first - \c second
deba@1720
   253
    /// ordered pair.
deba@1720
   254
    ///
deba@1720
   255
    /// Gives back the value assigned to the \c first - \c second ordered pair.
deba@1720
   256
    ConstReference operator()(const Key& first, const Key& second) const {
deba@1999
   257
      return values[index(Parent::getNotifier()->id(first), 
deba@1999
   258
                          Parent::getNotifier()->id(second))];
deba@1720
   259
    }
deba@1720
   260
    
deba@1720
   261
    /// \brief Gives back the value assigned to the \c first - \c second
deba@1720
   262
    /// ordered pair.
deba@1720
   263
    ///
deba@1720
   264
    /// Gives back the value assigned to the \c first - \c second ordered pair.
deba@1720
   265
    Reference operator()(const Key& first, const Key& second) {
deba@1999
   266
      return values[index(Parent::getNotifier()->id(first), 
deba@1999
   267
                          Parent::getNotifier()->id(second))];
deba@1720
   268
    }
deba@1720
   269
deba@1720
   270
    /// \brief Setter function for the matrix map.
deba@1720
   271
    ///
deba@1720
   272
    /// Setter function for the matrix map.
deba@1720
   273
    void set(const Key& first, const Key& second, const Value& val) {
deba@1999
   274
      values[index(Parent::getNotifier()->id(first), 
deba@1999
   275
                   Parent::getNotifier()->id(second))] = val;
deba@1720
   276
    }
deba@1720
   277
deba@1720
   278
  protected:
deba@1720
   279
deba@1720
   280
    static int index(int i, int j) {
deba@1720
   281
      if (i < j) {
deba@1720
   282
	return j * j + i;
deba@1720
   283
      } else {
deba@1720
   284
	return i * i + i + j;
deba@1720
   285
      }
deba@1720
   286
    }
deba@1720
   287
deba@1720
   288
    static int size(int s) {
deba@1720
   289
      return s * s;
deba@1720
   290
    }
deba@1720
   291
deba@1720
   292
    virtual void add(const Key& key) {
deba@1999
   293
      if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
deba@1999
   294
	values.resize(size(Parent::getNotifier()->id(key) + 1));	
deba@1720
   295
      }
deba@1720
   296
    }
deba@1720
   297
deba@1720
   298
    virtual void erase(const Key&) {}
deba@1720
   299
deba@1720
   300
    virtual void build() {
deba@1999
   301
      values.resize(size(Parent::getNotifier()->maxId() + 1));
deba@1720
   302
    }
deba@1720
   303
deba@1720
   304
    virtual void clear() {
deba@1720
   305
      values.clear();
deba@1720
   306
    }   
deba@1720
   307
    
deba@1720
   308
  private:
deba@1720
   309
    std::vector<Value> values;
deba@1720
   310
  };
deba@1720
   311
deba@1720
   312
  /// \brief Container for store values for each unordered pair of graph items
deba@1720
   313
  ///
alpar@1757
   314
  /// This data structure can strore for each pair of the same item
deba@1720
   315
  /// type a value. It increase the size of the container when the 
deba@1720
   316
  /// associated graph modified, so it updated automaticly whenever
deba@1720
   317
  /// it is needed. 
deba@1720
   318
  template <typename _Graph, typename _Item, typename _Value>
deba@1720
   319
  class DynamicSymMatrixMap 
deba@1999
   320
    : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
deba@1720
   321
  public:
deba@1999
   322
    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase 
deba@1999
   323
    Parent;
deba@1720
   324
deba@1720
   325
    typedef _Graph Graph;
deba@1720
   326
    typedef _Item Key;
deba@1720
   327
deba@1720
   328
    typedef _Item FirstKey;
deba@1720
   329
    typedef _Item SecondKey;
deba@1720
   330
    typedef _Value Value;
deba@1720
   331
deba@1720
   332
    typedef True ReferenceMapTag;
deba@1720
   333
deba@1720
   334
  private:
deba@1720
   335
		
deba@1720
   336
    typedef std::vector<Value> Container;
deba@1720
   337
deba@1720
   338
  public:
deba@1720
   339
deba@1720
   340
    typedef typename Container::reference Reference;
deba@1720
   341
    typedef typename Container::const_reference ConstReference;
deba@1720
   342
deba@1720
   343
    /// \brief Creates an item matrix for the given graph
deba@1720
   344
    ///
deba@1720
   345
    /// Creates an item matrix for the given graph.
deba@1720
   346
    DynamicSymMatrixMap(const Graph& _graph) 
deba@1999
   347
      : values(size(_graph.maxId(Key()) + 1)) {
deba@1999
   348
      Parent::attach(_graph.getNotifier(Key()));
deba@1720
   349
    }
deba@1720
   350
deba@1720
   351
    /// \brief Creates an item matrix for the given graph
deba@1720
   352
    ///
deba@1720
   353
    /// Creates an item matrix for the given graph and assigns for each
deba@1720
   354
    /// pairs of keys the given parameter.
deba@1720
   355
    DynamicSymMatrixMap(const Graph& _graph, const Value& _val) 
deba@1999
   356
      : values(size(_graph.maxId(Key()) + 1), _val) {
deba@1999
   357
      Parent::attach(_graph.getNotifier(Key()));
deba@1720
   358
    }
deba@1720
   359
deba@1720
   360
    /// \brief Gives back the value assigned to the \c first - \c second
deba@1720
   361
    /// unordered pair.
deba@1720
   362
    ///
deba@1720
   363
    /// Gives back the value assigned to the \c first - \c second unordered 
deba@1720
   364
    /// pair.
deba@1720
   365
    ConstReference operator()(const Key& first, const Key& second) const {
deba@1999
   366
      return values[index(Parent::getNotifier()->id(first), 
deba@1999
   367
                          Parent::getNotifier()->id(second))];
deba@1720
   368
    }
deba@1720
   369
    
deba@1720
   370
    /// \brief Gives back the value assigned to the \c first - \c second
deba@1720
   371
    /// unordered pair.
deba@1720
   372
    ///
deba@1720
   373
    /// Gives back the value assigned to the \c first - \c second unordered 
deba@1720
   374
    /// pair.
deba@1720
   375
    Reference operator()(const Key& first, const Key& second) {
deba@1999
   376
      return values[index(Parent::getNotifier()->id(first), 
deba@1999
   377
                          Parent::getNotifier()->id(second))];
deba@1720
   378
    }
deba@1720
   379
deba@1720
   380
    /// \brief Setter function for the matrix map.
deba@1720
   381
    ///
deba@1720
   382
    /// Setter function for the matrix map.
deba@1720
   383
    void set(const Key& first, const Key& second, const Value& val) {
deba@1999
   384
      values[index(Parent::getNotifier()->id(first), 
deba@1999
   385
                   Parent::getNotifier()->id(second))] = val;
deba@1720
   386
    }
deba@1720
   387
deba@1720
   388
  protected:
deba@1720
   389
deba@1720
   390
    static int index(int i, int j) {
deba@1720
   391
      if (i < j) {
deba@1720
   392
	return j * (j + 1) / 2 + i;
deba@1720
   393
      } else {
deba@1720
   394
	return i * (i + 1) / 2 + j;
deba@1720
   395
      }
deba@1720
   396
    }
deba@1720
   397
deba@1720
   398
    static int size(int s) {
deba@1720
   399
      return s * (s + 1) / 2;
deba@1720
   400
    }
deba@1720
   401
deba@1720
   402
    virtual void add(const Key& key) {
deba@1999
   403
      if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
deba@1999
   404
	values.resize(size(Parent::getNotifier()->id(key) + 1));	
deba@1720
   405
      }
deba@1720
   406
    }
deba@1720
   407
deba@1720
   408
    virtual void erase(const Key&) {}
deba@1720
   409
deba@1720
   410
    virtual void build() {
deba@1999
   411
      values.resize(size(Parent::getNotifier()->maxId() + 1));
deba@1720
   412
    }
deba@1720
   413
deba@1720
   414
    virtual void clear() {
deba@1720
   415
      values.clear();
deba@1720
   416
    }   
deba@1720
   417
    
deba@1720
   418
  private:
deba@1720
   419
    std::vector<Value> values;
deba@1720
   420
  };
deba@1720
   421
deba@1720
   422
}
deba@1720
   423
deba@1720
   424
#endif