00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00038 #ifndef DETERMINANT_H
00039 #define DETERMINANT_H
00040
00041 #include <LEP/mcb/spvecfp.h>
00042 #include <LEP/mcb/edge_num.h>
00043 #include <LEP/mcb/util.h>
00044
00045 #ifdef LEDA_GE_V5
00046 #include <LEDA/graph/graph.h>
00047 #include <LEDA/numbers/integer.h>
00048 #include <LEDA/numbers/integer_matrix.h>
00049 #else
00050 #include <LEDA/graph.h>
00051 #include <LEDA/integer.h>
00052 #include <LEDA/integer_matrix.h>
00053 #endif
00054
00055
00056 namespace mcb
00057 {
00058
00059 #if defined(LEDA_NAMESPACE)
00060 using leda::graph;
00061 using leda::array;
00062 using leda::edge;
00063 using leda::node;
00064 using leda::integer_matrix;
00065 #endif
00066
00068
00093 template<class Container>
00094 void cycle_matrix ( const graph& g,
00095 const array<Container>& cb,
00096 const mcb::edge_num& enumb,
00097 integer_matrix& B )
00098 {
00099 int N = enumb.dim_cycle_space();
00100 if ( N == 0 )
00101 leda::error_handler(999,"determinant: cycle space dimension is zero!");
00102
00103 if ( B.dim1() != N || B.dim2() != N )
00104 leda::error_handler(999,"determinant: matrix has wrong dimensions!");
00105
00106 array< mcb::spvecfp > oriented_cb ( N );
00107 CycleOrienter<Container> orienter( g, enumb );
00108 for( int i = 0; i < N; ++i )
00109 oriented_cb[i] = orienter( cb[i] );
00110
00111 cycle_matrix<mcb::spvecfp>( g, oriented_cb, enumb, B );
00112 }
00113
00114 template<>
00115 void cycle_matrix<mcb::spvecfp> ( const graph& g,
00116 const array<mcb::spvecfp>& cb,
00117 const mcb::edge_num& enumb,
00118 integer_matrix& B )
00119 {
00120 int N = enumb.dim_cycle_space();
00121 if ( N == 0 )
00122 leda::error_handler(999,"cycle_matrix: cycle space dimension is zero!");
00123
00124 if ( B.dim1() != N || B.dim2() != N )
00125 leda::error_handler(999,"cycle_matrix: matrix must have dimension NxN!");
00126
00127 for( int i = 0; i < N; ++i ) {
00128 leda::list_item it = cb[i].first();
00129 while(it!=nil)
00130 {
00131 int index = cb[i].index(it);
00132 if( ! enumb.tree( enumb( index ) ) )
00133 {
00134 B[i][index] = cb[i].inf(it);
00135 }
00136 it = cb[i].succ(it);
00137 }
00138 }
00139 }
00140
00141
00142
00149 std::ostream& output_maple_format( std::ostream& out, const integer_matrix& B );
00150
00151
00163 template<class Container>
00164 leda::integer determinant ( const graph& g,
00165 const array< Container >& cb,
00166 const mcb::edge_num& enumb
00167 )
00168 {
00169 int N = enumb.dim_cycle_space();
00170 if ( N == 0 )
00171 leda::error_handler(999,"determinant: cycle space dimension is zero!");
00172
00173 integer_matrix B( N, N );
00174 cycle_matrix<Container>( g, cb, enumb, B );
00175
00176 leda::integer d = abs( determinant(B) );
00177 if ( d == 0 )
00178 leda::error_handler(999,"determinant: not a directed cycle basis!");
00179 return d;
00180 }
00181
00182
00184
00185 }
00186
00187 #endif // DETERMINANT_H
00188
00189
00190
00191