File: LG_check_mis.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (127 lines) | stat: -rw-r--r-- 4,333 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//------------------------------------------------------------------------------
// LG_check_mis: test if iset is a maximal independent set
//------------------------------------------------------------------------------

// LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
// SPDX-License-Identifier: BSD-2-Clause
//
// For additional details (including references to third party source code and
// other files) see the LICENSE file or contact permission@sei.cmu.edu. See
// Contributors.txt for a full list of contributors. Created, in part, with
// funding and support from the U.S. Government (see Acknowledgments.txt file).
// DM22-0790

// Contributed by Timothy A. Davis, Texas A&M University

//------------------------------------------------------------------------------

#define LG_FREE_WORK                    \
{                                       \
    GrB_free (&C) ;                     \
    LAGraph_Free ((void **) &I, NULL) ; \
    LAGraph_Free ((void **) &X, NULL) ; \
}

#define LG_FREE_ALL                     \
{                                       \
    LG_FREE_WORK ;                      \
}

#include "LG_internal.h"
#include "LG_test.h"

int LG_check_mis        // check if iset is a valid MIS of A
(
    GrB_Matrix A,
    GrB_Vector iset,
    GrB_Vector ignore_node,     // if NULL, no nodes are ignored.  otherwise,
                        // ignore_node(i)=true if node i is to be ignored, and
                        // not added to the independent set.
    char *msg
)
{

    //--------------------------------------------------------------------------
    // check and report the results
    //--------------------------------------------------------------------------

    LG_CLEAR_MSG ;
    GrB_Matrix C = NULL ;
    GrB_Index *I = NULL ;
    bool *X = NULL ;

    GrB_Index n ;
    GRB_TRY (GrB_Matrix_nrows (&n, A)) ;

    int64_t isize ;
    GRB_TRY (GrB_Vector_reduce_INT64 (&isize, NULL, GrB_PLUS_MONOID_INT64,
        iset, NULL)) ;

    GrB_Index nvals ;
    GRB_TRY (GrB_Vector_nvals (&nvals, iset)) ;
    LAGRAPH_TRY (LAGraph_Malloc ((void **) &I, nvals, sizeof (GrB_Index), msg));
    LAGRAPH_TRY (LAGraph_Malloc ((void **) &X, nvals, sizeof (bool), msg)) ;

    GRB_TRY (GrB_Vector_extractTuples_BOOL (I, X, &nvals, iset)) ;

    // I [0..isize-1] is the independent set
    isize = 0 ;
    for (int64_t k = 0 ; k < nvals ; k++)
    {
        if (X [k])
        {
            I [isize++] = I [k] ;
        }
    }

    LAGraph_Free ((void **) &X, NULL) ;

    // printf ("independent set found: %.16g of %.16g nodes\n",
    // (double) isize, (double) n) ;

    //--------------------------------------------------------------------------
    // verify the result
    //--------------------------------------------------------------------------

    // C = A(I,I) must be empty, except for diagonal entries
    GRB_TRY (GrB_Matrix_new (&C, GrB_BOOL, isize, isize)) ;
    GRB_TRY (GrB_Matrix_extract (C, NULL, NULL, A, I, isize, I, isize, NULL)) ;
    GRB_TRY (GrB_select (C, NULL, NULL, GrB_OFFDIAG, C, 0, NULL)) ;
    GRB_TRY (GrB_Matrix_nvals (&nvals, C)) ;
    LG_ASSERT_MSG (nvals == 0, -1, "error!  A(I,I) has an edge!\n") ;
    GrB_Matrix_free (&C) ;

    // now check if all other nodes are adjacent to the iset

    // e = iset
    GrB_Vector e = NULL ;
    GRB_TRY (GrB_Vector_dup (&e, iset)) ;

    // e = e || ignore_node
    int64_t ignored = 0 ;
    if (ignore_node != NULL)
    {
        GRB_TRY (GrB_eWiseAdd (e, NULL, NULL, GrB_LOR, e, ignore_node, NULL)) ;
        GRB_TRY (GrB_reduce (&ignored, NULL, GrB_PLUS_MONOID_INT64,
            ignore_node, NULL)) ;
    }

    // e = (e || A*iset), using the structural semiring
    GRB_TRY (GrB_vxm (e, NULL, GrB_LOR, LAGraph_any_one_bool, iset, A, NULL)) ;

    // drop explicit zeros from e
    // e<e.replace> = e
    GRB_TRY (GrB_assign (e, e, NULL, e, GrB_ALL, n, GrB_DESC_R)) ;

    GRB_TRY (GrB_Vector_nvals (&nvals, e)) ;
    GrB_Vector_free (&e) ;
    LG_ASSERT_MSG (nvals == n, -1, "error! A (I,I is not maximal!\n") ;

    LAGraph_Free ((void **) &I, NULL) ;

    printf ("maximal independent set OK %.16g of %.16g nodes",
        (double) isize, (double) n) ;
    if (ignored > 0) printf (" (%g nodes ignored)\n", (double) ignored) ;
    printf ("\n") ;
    return (GrB_SUCCESS) ;
}