Polaris: SimBiGraph.cc Source File

SimBiGraph.cc

Go to the documentation of this file.
00001 ///
00002 /// \file SimGraph.cc
00003 ///
00004 #ifdef POLARIS_GNU_PRAGMAS
00005 #pragma implementation
00006 #endif
00007 ///
00008 #include "SimBiGraph.h"
00009 #include "UEdge.h"
00010 #include "utilities/access_util.h"
00011 #include "utilities/stmt_util.h"
00012 #include "Range/Relation.h"
00013 #include "Range/RangeAccessor.h"
00014 #include "UBiGraphIterator.h"
00015 
00016 /// Create an empty graph
00017 SimBiGraph::SimBiGraph( ) {
00018     #ifdef CLASS_INSTANCE_REGISTRY
00019     register_instance(SIM_BIGRAPH, sizeof(SimBiGraph), this);
00020     #endif
00021 
00022     _ptrs1 = new Array< RefElement< AbstractAccess > >;
00023     _ptrs2 = new Array< RefElement< AbstractAccess > >;
00024     _graph = new Array<Array<SimEdgeKernel> >;
00025     _nodes1 = 0;
00026     _nodes2 = 0;
00027 }
00028 
00029 /// Create a complete graph with given number of nodes
00030 
00031 SimBiGraph::SimBiGraph(List<AbstractAccess> & list1, 
00032                List<AbstractAccess> & list2)
00033 {
00034     #ifdef CLASS_INSTANCE_REGISTRY
00035     register_instance(SIM_BIGRAPH, sizeof(SimBiGraph), this);
00036     #endif
00037 
00038     /// ...  Make a complete graph with the proper number of nodes
00039 
00040     _nodes1 = list1.entries();
00041     _nodes2 = list2.entries();
00042 
00043     _ptrs1 = 0;
00044     _ptrs2 = 0;
00045     _graph = 0;
00046 
00047     if ((_nodes1 == 0) || (_nodes2 == 0)) return;
00048 
00049     _ptrs1 = new Array< RefElement< AbstractAccess > >;
00050     _ptrs2 = new Array< RefElement< AbstractAccess > >;
00051     _graph  = new Array<Array<SimEdgeKernel> >;
00052 
00053     _ptrs1->resize(_nodes1);
00054     _graph->resize(_nodes1);
00055     _ptrs2->resize(_nodes2);
00056 
00057     Iterator<AbstractAccess> iter = list1; 
00058     for (int i = 0;  iter.valid(); ++iter,++i) {
00059 
00060     (*_ptrs1)[i] = iter.current();
00061     (*_graph)[i].resize(_nodes2);
00062     }
00063 
00064     Iterator<AbstractAccess> iter2 = list2; 
00065     for (int i = 0;  iter2.valid(); ++iter2,++i) {
00066 
00067     (*_ptrs2)[i] = iter2.current();
00068     }
00069 
00070     /// ...  Initialized each edge to SIM_UNKNOWN
00071 
00072     for (int i=0; i<_nodes1; ++i) {
00073     for (int j=0; j<_nodes2; ++j) {
00074         (((*_graph)[i])[j]).type(SIM_UNKNOWN);
00075     }
00076     }
00077 
00078     Statement * r_stmt = range_stmt(*(list1[0]._summarized_to));
00079     String stmt_tag = r_stmt->tag();
00080     _range_acc = new RangeAccessor(list1[0]._pgm_summarized_to->range_dict_guarded(), 
00081                    *r_stmt );
00082     
00083     /// ...  Compare each pair of descriptors, building the Similarity graph as we go
00084 
00085     for (int i=0; i<_nodes1; ++i) {
00086     for (int j=0; j<_nodes2; ++j) {
00087         calc_similarity( i, j );
00088     }
00089     }
00090 }
00091 
00092 void
00093 SimBiGraph::print_similarities( ) const
00094 {
00095     if (_ar_logging && _ar_logging % 5 == 0) {
00096     arlog << "BI-Graph" << endl;
00097 
00098     for (int i=0; i<_nodes1; ++i) {
00099         arlog << "[" << i << "]" ;
00100         AbstractAccess & aa = *((*_ptrs1)[i]);
00101         int ndims1 = aa.number_of_dimensions();
00102         for (int j=0; j<_nodes2; ++j) {
00103         AbstractAccess & aa2 = *((*_ptrs2)[j]);
00104         SimEdgeKernel & sek = ((*_graph)[i])[j];
00105         int ndims2 = aa2.number_of_dimensions();
00106         arlog << "    " << sek.type_name() << "[" ;
00107         if ((i != j) && (ndims1 == ndims2) && 
00108             (sek.type() != SIM_NOT_SIMILAR)) {
00109             for (int k=0; k<aa.number_of_dimensions(); ++k) {
00110             arlog << (*(sek.stridematch()))[k] << ":" ;
00111             if ((*(sek.spanmatch()))[k]) {
00112                 arlog << "T";
00113             } else {
00114                 arlog << "F";
00115             }
00116             }
00117         }
00118         arlog << "]";
00119         }
00120         arlog << endl;
00121     }
00122     }
00123 }
00124 
00125 
00126 /// Create a copy of a given graph
00127 
00128 SimBiGraph::SimBiGraph( const SimBiGraph & other ) {
00129     #ifdef CLASS_INSTANCE_REGISTRY
00130     register_instance(SIM_BIGRAPH, sizeof(SimBiGraph), this);
00131     #endif
00132 
00133     _nodes1 = other._nodes1;
00134     _nodes2 = other._nodes2;
00135     _ptrs1 = new Array< RefElement< AbstractAccess > >;
00136     _ptrs2 = new Array< RefElement< AbstractAccess > >;
00137     _graph  = new Array< Array< SimEdgeKernel > >;
00138 
00139     _ptrs1->resize(_nodes1);
00140     _ptrs2->resize(_nodes2);
00141     _graph->resize(_nodes1);
00142 
00143     for (int i = 0; i<_nodes1; ++i) {
00144     (*_ptrs1)[i] = (*(other._ptrs1))[i];
00145     (*_graph)[i].resize(_nodes2);
00146     }
00147 
00148     for (int i = 0; i<_nodes2; ++i) {
00149     (*_ptrs2)[i] = (*(other._ptrs2))[i];
00150     }
00151 
00152     for (int i=0; i < _nodes1; ++i) {
00153     for (int j=0; j < _nodes2; ++j) {
00154         ((*_graph)[i])[j] = ((*(other._graph))[i])[j];
00155     }
00156     }
00157 }
00158 
00159 /// Return the number of nodes in the graph for list1
00160 
00161 int
00162 SimBiGraph::nodes1( )
00163 {
00164     return _nodes1;
00165 }
00166 
00167 /// Return the number of nodes in the graph for list2
00168 
00169 int
00170 SimBiGraph::nodes2( )
00171 {
00172     return _nodes2;
00173 }
00174 
00175 SimBiGraph::~SimBiGraph( )
00176 {
00177     #ifdef CLASS_INSTANCE_REGISTRY
00178     unregister_instance(SIM_BIGRAPH, this);
00179     #endif
00180 
00181     if (_ptrs1) {
00182     delete _ptrs1;
00183     _ptrs1 = 0;
00184     }
00185 
00186     if (_ptrs2) {
00187     delete _ptrs2;
00188     _ptrs2 = 0;
00189     }
00190 
00191     if (_graph) {
00192     delete _graph;
00193     _graph = 0;
00194     }
00195 
00196     if (_range_acc) {
00197     delete _range_acc;
00198     _range_acc = 0;
00199     }
00200 }
00201 
00202 /// Calculate the similarity relationship between nodes i and j in the Similarity graph
00203 
00204 void
00205 SimBiGraph::calc_similarity( int i, int j )
00206 {
00207 
00208     AbstractAccess & descr1 = *((*_ptrs1)[ i ]);
00209     int ndims1 = descr1.number_of_dimensions();
00210 
00211     AbstractAccess & descr2 = *((*_ptrs2)[ j ]);
00212     int ndims2 = descr2.number_of_dimensions();
00213 
00214     SimEdgeKernel & kernelij = ((*_graph)[i])[j];
00215 
00216     SimilarityType orig_ij_type = kernelij.type();
00217     SimilarityType calc_ij_type;
00218 
00219     /// ...  If already filled in, skip it
00220     if ((orig_ij_type != SIM_UNKNOWN ) &&
00221     (orig_ij_type != SIM_DIM_EQUIV_UP ) &&
00222     (orig_ij_type != SIM_STRIDE_EQUIV_UP )) return;
00223     
00224     bool equal_dim_count;
00225 
00226     if (ndims1 == ndims2) {
00227     equal_dim_count = true;
00228     } else {
00229     equal_dim_count = false;
00230     }
00231 
00232     bool matchoff = false;
00233     bool matchstrides, matchspans;
00234 
00235     Array<int> * stride_match1;
00236     Array<int> * stride_match2=0;
00237     Array<bool> * span_match1;
00238     Array<bool> * span_match2=0;
00239 
00240     /// ...  Do the offsets match?
00241 
00242     if (is_integer_zero(descr1.start_guarded()) &&
00243     is_integer_zero(descr2.start_guarded())) {
00244     matchoff = true;
00245     } else {
00246     const Relation & reloff = _range_acc->compare(descr1.start_guarded(),
00247                               descr2.start_guarded());
00248     if (reloff.is_equal()) {
00249         matchoff = true;
00250     }
00251     }
00252 
00253     /// ...  If these two descriptors were already found dimension-equivalent,
00254     /// ...  check offsets to see whether they are totally equivalent.  Then we
00255     /// ...  can avoid all the rest of the equivalency checks.
00256 
00257     if (orig_ij_type == SIM_DIM_EQUIV_UP) {
00258     if (matchoff) {
00259         calc_ij_type = SIM_EQUIV;
00260     } else {
00261         calc_ij_type = SIM_DIM_EQUIV;
00262     }
00263     kernelij.type(calc_ij_type);
00264 
00265     stride_match1 = kernelij.stridematch();
00266     span_match1 = kernelij.spanmatch();
00267 
00268     } else {
00269 
00270     /// ...  Compare one dimension from each descriptor
00271 
00272     stride_match1 = new Array<int>;
00273     stride_match1->resize(ndims1);
00274 
00275     stride_match2 = new Array<int>;
00276     stride_match2->resize(ndims2);
00277 
00278     span_match1 = new Array<bool>;
00279     span_match1->resize(ndims1);
00280 
00281     span_match2 = new Array<bool>;
00282     span_match2->resize(ndims2);
00283 
00284     if (orig_ij_type == SIM_STRIDE_EQUIV_UP) {
00285             
00286         /// ...  Check only for a span match based on the previous stride match
00287 
00288         Array<int> * temp1 = kernelij.stridematch();
00289         for (int ii=0; ii<ndims1; ++ii) {
00290         (*stride_match1)[ii] = (*temp1)[ii];
00291         }
00292         
00293     } else {   
00294 
00295         calc_stride_span_match(descr1, descr2, *_range_acc,
00296                    *stride_match1, *stride_match2,
00297                    *span_match1, *span_match2);
00298     }
00299         
00300     /// ...  Now, check for a match.
00301 
00302     if (orig_ij_type == SIM_STRIDE_EQUIV_UP) {
00303         matchstrides = true;  /// ...  Already asserted that strides are equiv
00304     } else {
00305         matchstrides = true;
00306 
00307         /// ...  Check whether all dimensions of at least one descriptor 
00308         /// ...  have a matching dimension.
00309 
00310         int count1 = 0;
00311         for (int ii=0; ii<ndims1; ++ii) {
00312         if ((*stride_match1)[ii] != -1) {
00313             count1++;
00314         }
00315         }
00316         int count2 = 0;
00317         for (int ii=0; ii<ndims2; ++ii) {
00318         if ((*stride_match2)[ii] != -1) {
00319             count2++;
00320         }
00321         }
00322 
00323         p_assert(count1 == count2, "Stride-match is not reflexive");
00324 
00325         if ((count1 != ndims1) && (count2 != ndims2)) {
00326         matchstrides = false;
00327         }
00328 
00329     }
00330     matchspans = true;
00331     for (int ii=0; ii<ndims1; ++ii) {
00332         if (((*stride_match1)[ii] != -1) && (! (*span_match1)[ii])) {
00333         matchspans = false;
00334         break;
00335         }
00336     }
00337 
00338     if (matchoff && matchstrides && matchspans && equal_dim_count) {
00339         calc_ij_type = SIM_EQUIV;
00340     } else if (matchoff && matchstrides && matchspans) {
00341         calc_ij_type = SIM_EQUIV_SEMI;
00342     } else if (matchstrides && matchspans && equal_dim_count) {
00343         calc_ij_type = SIM_DIM_EQUIV;
00344     } else if (matchstrides && matchspans) {
00345         calc_ij_type = SIM_DIM_EQUIV_SEMI;
00346     } else if (matchstrides && equal_dim_count) {
00347         calc_ij_type = SIM_STRIDE_EQUIV;
00348     } else if (matchstrides) {
00349         calc_ij_type = SIM_STRIDE_EQUIV_SEMI;
00350     } else {
00351         calc_ij_type = SIM_NOT_SIMILAR;
00352     }
00353 
00354     kernelij.dump_in_match( calc_ij_type, stride_match1, span_match1 );
00355     }
00356     /// ...  silvius:
00357     if (span_match2){
00358       delete span_match2;
00359     }
00360     if (stride_match2){
00361       delete stride_match2;
00362     }
00363 }
00364 
00365 RangeAccessor *
00366 SimBiGraph::range_acc(  )
00367 {
00368     return _range_acc;
00369 }
00370 
00371 SimBiGraph *
00372 SimBiGraph::clone() const
00373 {
00374     return new SimBiGraph( (SimBiGraph &)*this );
00375 }
00376 
00377 Listable *
00378 SimBiGraph::listable_clone() const
00379 {
00380     return (Listable *) clone();
00381 }
00382 
00383 void
00384 SimBiGraph::print(ostream & o) const 
00385 {
00386     o << "{ Nodes: (" << _nodes1 << "," << _nodes2 << ")" << "; Ptrs: " << *_ptrs1 << "; Graph: " << *_graph << "}";
00387 }
00388 
00389 ostream & 
00390 operator << (ostream & o, const SimBiGraph & graph) 
00391 {
00392     graph.print(o);
00393     return o;
00394 }
00395 
00396 SimEdgeKernel &
00397 SimBiGraph::kernel(int i, int j)
00398 {
00399     return ((*_graph)[i])[j];
00400 }
00401 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:07 2005