determinant.h

Go to the documentation of this file.
00001 //
00002 // This program can be freely used in an academic environment
00003 // ONLY for research purposes, subject to the following restrictions:
00004 //
00005 // 1. The origin of this software must not be misrepresented; you must not
00006 //    claim that you wrote the original software. If you use this software
00007 //    an acknowledgment in the product documentation is required.
00008 // 2. Altered source versions must be plainly marked as such, and must not be
00009 //    misrepresented as being the original software.
00010 // 3. This notice may not be removed or altered from any source distribution.
00011 //
00012 // Any other use is strictly prohibited by the author, without an explicit 
00013 // permission.
00014 //
00015 // Note that this program uses the LEDA library, which is NOT free. For more 
00016 // details visit Algorithmic Solutions at http://www.algorithmic-solutions.com/
00017 // There is also a free version of LEDA 6.0 or newer.
00018 //
00019 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00020 // ! Any commercial use of this software is strictly !
00021 // ! prohibited without explicit permission by the   !
00022 // ! author.                                         !
00023 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00024 //
00025 // This software is distributed in the hope that it will be useful,
00026 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00027 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00028 //
00029 // Copyright (C) 2004-2008 - Dimitris Michail <dmixdim@googlemail.com>, <michail@mpi-inf.mpg.de>
00030 //
00031 // $Id: determinant.h 7030 2008-04-18 00:48:38Z dmichail $
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 // start our namespace
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 } // namespace mcb end
00186 
00187 #endif  // DETERMINANT_H
00188 
00189 /* ex: set ts=4 sw=4 sts=4 et: */
00190 
00191 

Generated on Tue Apr 22 13:40:09 2008 for mcb LEDA Extension Package by  doxygen 1.4.6