/*******************************************************************************
+
+  LEDA 3.5
+
+  node_matrix.h
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
#ifndef LEDA_NODE_MATRIX_H
#define LEDA_NODE_MATRIX_H

#if !defined(LEDA_ROOT_INCL_ID)
#define LEDA_ROOT_INCL_ID 350082
#include <LEDA/REDEFINE_NAMES.h>
#endif


/*{\Manpage {node_matrix} {E} {Two Dimensional Node Arrays}}*/

template<class E>

class node_matrix {

/*{\Mdefinition
An instance $M$ of the parameterized data type |\Mname| is
a partial mapping from the set of node pairs $V\times V$
of a graph to the set of variables of data type $E$, called the element type
of $M$. The domain $I$ of $M$ is called the index set of $M$. $M$ is said to
be valid for all node pairs in $I$. A node matrix can also be viewed as a
node array with element type $node\_array\<E\>$ ($node\_array\<node\_array\<E\>\ \>$).
}*/

node_array<node_array<E> > M;

public:

/*{\Mcreation M }*/

node_matrix() {}
/*{\Mcreate creates an instance $M$ of type |\Mname| and initializes the index 
            set of $M$ to the empty set. }*/

node_matrix(const graph& G)  { init(G);   }
/*{\Mcreate creates an instance $M$ of type |\Mname| and initializes the index 
            set to be the set of all node pairs of graph $G$, i.e., $M$ is made 
            valid for all pairs in $V \times V$ where $V$ is the set of nodes 
            currently contained in $G$.
}*/

node_matrix(const graph& G, E x) { init(G,x); }
/*{\Mcreate creates an instance $M$ of type |\Mname| and initializes the index 
            set of $M$ to be the set of all node pairs of graph $G$, i.e., $M$ 
            is made valid for all pairs in $V \times V$ where $V$ is the set of 
            nodes currently contained in $G$.  In addition, $M(v,w)$ is 
            initialized with $x$ for all 
nodes $v,w \in V$.}*/

 node_matrix(const node_matrix<E>& mat) : M(mat.M) {}

 node_matrix<E>& operator=(const node_matrix<E>& mat) 
{ M = mat.M; return *this; }

~node_matrix() {}


/*{\Moperations 3.2 3.7}*/

void  init(const graph& G)
{ M.init(G); 
  node v;
  forall_nodes(v,G) M[v].init(G);
}
/*{\Mop       sets the index set of $M$ to $V\times V$, where  
	      $V$ is the set of all nodes of $G$. }*/


void  init(const graph& G, E x)
{ M.init(G); 
  node v;
  forall_nodes(v,G) M[v].init(G,x);
}
/*{\Mopl      sets the index set of $M$ to $V\times V$, where
	      $V$ is the set of all nodes of $G$ and initializes
	      $M(v,w)$ to $x$ for all $v,w \in V$.}*/


/*{\Moptions nextwarning=no }*/
const node_array<E>& operator[](node v) const { return M[v]; }
      node_array<E>& operator[](node v)       { return M[v]; }
/*{\Marrop    returns the node\_array  $M(v)$.}*/


/*{\Moptions nextwarning=no }*/
const E&  operator()(node v, node w) const { return M[v][w]; }
      E&  operator()(node v, node w)       { return M[v][w]; }
/*{\Mfunop    returns the variable $M(v,w)$.\\
	      \precond $M$ must be valid for $v$ and $w$.}*/

};

/*{\Mimplementation
Node matrices for a graph $G$ are implemented by vectors of node arrays and an 
internal numbering of the nodes of $G$. The access operation 
takes constant time, the init operation takes time $O(n^2)$, where $n$ is the 
number of nodes currently contained in $G$. The space requirement is $O(n^2)$.
Note that a node matrix is only valid for the nodes contained in $G$ at the 
moment of the matrix declaration or initialization ($init$). Access operations 
for later added nodes are not allowed.}*/



#if LEDA_ROOT_INCL_ID == 350082
#undef LEDA_ROOT_INCL_ID
#include <LEDA/UNDEFINE_NAMES.h>
#endif

#endif
