LCOV - code coverage report
Current view: top level - experimental/test - LG_check_mis.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: cc56ed4. Current time (UTC): 2024-08-30T17:14:30Z Lines: 38 38 100.0 %
Date: 2024-08-30 17:16:41 Functions: 1 1 100.0 %

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LG_check_mis: test if iset is a maximal independent set
       3             : //------------------------------------------------------------------------------
       4             : 
       5             : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
       6             : // SPDX-License-Identifier: BSD-2-Clause
       7             : //
       8             : // For additional details (including references to third party source code and
       9             : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
      10             : // Contributors.txt for a full list of contributors. Created, in part, with
      11             : // funding and support from the U.S. Government (see Acknowledgments.txt file).
      12             : // DM22-0790
      13             : 
      14             : // Contributed by Timothy A. Davis, Texas A&M University
      15             : 
      16             : //------------------------------------------------------------------------------
      17             : 
      18             : #define LG_FREE_WORK                    \
      19             : {                                       \
      20             :     GrB_free (&C) ;                     \
      21             :     LAGraph_Free ((void **) &I, NULL) ; \
      22             :     LAGraph_Free ((void **) &X, NULL) ; \
      23             : }
      24             : 
      25             : #define LG_FREE_ALL                     \
      26             : {                                       \
      27             :     LG_FREE_WORK ;                      \
      28             : }
      29             : 
      30             : #include "LG_internal.h"
      31             : #include "LG_test.h"
      32             : 
      33         339 : int LG_check_mis        // check if iset is a valid MIS of A
      34             : (
      35             :     GrB_Matrix A,
      36             :     GrB_Vector iset,
      37             :     GrB_Vector ignore_node,     // if NULL, no nodes are ignored.  otherwise,
      38             :                         // ignore_node(i)=true if node i is to be ignored, and
      39             :                         // not added to the independent set.
      40             :     char *msg
      41             : )
      42             : {
      43             : 
      44             :     //--------------------------------------------------------------------------
      45             :     // check and report the results
      46             :     //--------------------------------------------------------------------------
      47             : 
      48         339 :     LG_CLEAR_MSG ;
      49         339 :     GrB_Matrix C = NULL ;
      50         339 :     GrB_Index *I = NULL ;
      51         339 :     bool *X = NULL ;
      52             : 
      53             :     GrB_Index n ;
      54         339 :     GRB_TRY (GrB_Matrix_nrows (&n, A)) ;
      55             : 
      56             :     int64_t isize ;
      57         339 :     GRB_TRY (GrB_Vector_reduce_INT64 (&isize, NULL, GrB_PLUS_MONOID_INT64,
      58             :         iset, NULL)) ;
      59             : 
      60             :     GrB_Index nvals ;
      61         339 :     GRB_TRY (GrB_Vector_nvals (&nvals, iset)) ;
      62         339 :     LAGRAPH_TRY (LAGraph_Malloc ((void **) &I, nvals, sizeof (GrB_Index), msg));
      63         339 :     LAGRAPH_TRY (LAGraph_Malloc ((void **) &X, nvals, sizeof (bool), msg)) ;
      64             : 
      65         339 :     GRB_TRY (GrB_Vector_extractTuples_BOOL (I, X, &nvals, iset)) ;
      66             : 
      67             :     // I [0..isize-1] is the independent set
      68         339 :     isize = 0 ;
      69       46320 :     for (int64_t k = 0 ; k < nvals ; k++)
      70             :     {
      71       45981 :         if (X [k])
      72             :         {
      73       45981 :             I [isize++] = I [k] ;
      74             :         }
      75             :     }
      76             : 
      77         339 :     LAGraph_Free ((void **) &X, NULL) ;
      78             : 
      79             :     // printf ("independent set found: %.16g of %.16g nodes\n",
      80             :     // (double) isize, (double) n) ;
      81             : 
      82             :     //--------------------------------------------------------------------------
      83             :     // verify the result
      84             :     //--------------------------------------------------------------------------
      85             : 
      86             :     // C = A(I,I) must be empty, except for diagonal entries
      87         339 :     GRB_TRY (GrB_Matrix_new (&C, GrB_BOOL, isize, isize)) ;
      88         339 :     GRB_TRY (GrB_Matrix_extract (C, NULL, NULL, A, I, isize, I, isize, NULL)) ;
      89         339 :     GRB_TRY (GrB_select (C, NULL, NULL, GrB_OFFDIAG, C, 0, NULL)) ;
      90         339 :     GRB_TRY (GrB_Matrix_nvals (&nvals, C)) ;
      91         339 :     LG_ASSERT_MSG (nvals == 0, -1, "error!  A(I,I) has an edge!\n") ;
      92         339 :     GrB_Matrix_free (&C) ;
      93             : 
      94             :     // now check if all other nodes are adjacent to the iset
      95             : 
      96             :     // e = iset
      97         339 :     GrB_Vector e = NULL ;
      98         339 :     GRB_TRY (GrB_Vector_dup (&e, iset)) ;
      99             : 
     100             :     // e = e || ignore_node
     101         339 :     int64_t ignored = 0 ;
     102         339 :     if (ignore_node != NULL)
     103             :     {
     104         160 :         GRB_TRY (GrB_eWiseAdd (e, NULL, NULL, GrB_LOR, e, ignore_node, NULL)) ;
     105         160 :         GRB_TRY (GrB_reduce (&ignored, NULL, GrB_PLUS_MONOID_INT64,
     106             :             ignore_node, NULL)) ;
     107             :     }
     108             : 
     109             :     // e = (e || A*iset), using the structural semiring
     110         339 :     GRB_TRY (GrB_vxm (e, NULL, GrB_LOR, LAGraph_any_one_bool, iset, A, NULL)) ;
     111             : 
     112             :     // drop explicit zeros from e
     113             :     // e<e.replace> = e
     114         339 :     GRB_TRY (GrB_assign (e, e, NULL, e, GrB_ALL, n, GrB_DESC_R)) ;
     115             : 
     116         339 :     GRB_TRY (GrB_Vector_nvals (&nvals, e)) ;
     117         339 :     GrB_Vector_free (&e) ;
     118         339 :     LG_ASSERT_MSG (nvals == n, -1, "error! A (I,I is not maximal!\n") ;
     119             : 
     120         339 :     LAGraph_Free ((void **) &I, NULL) ;
     121             : 
     122         339 :     printf ("maximal independent set OK %.16g of %.16g nodes",
     123             :         (double) isize, (double) n) ;
     124         339 :     if (ignored > 0) printf (" (%g nodes ignored)\n", (double) ignored) ;
     125         339 :     printf ("\n") ;
     126         339 :     return (GrB_SUCCESS) ;
     127             : }

Generated by: LCOV version 1.14