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

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LAGraph_KTruss: k-truss subgraph
       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             : // LAGraph_KTruss: k-truss subgraph.
      19             : 
      20             : // Given a symmetric graph A with no-self edges, LAGraph_KTruss finds the
      21             : // k-truss subgraph of A.
      22             : 
      23             : // The graph G must be undirected, or have an adjacency matrix with symmetric
      24             : // structure.  Only the structure of G->A is considered.  Its values are
      25             : // ignored.  G must not have any self-edges.
      26             : 
      27             : // The output matrix C is the k-truss subgraph of A.  Its edges are a subset of
      28             : // G->A.  Each edge in C is part of at least k-2 triangles in C.  The structure
      29             : // of C is the adjacency matrix of the k-truss subgraph of A.  The edge weights
      30             : // of C are the support of each edge.  That is, C(i,j)=nt if the edge (i,j) is
      31             : // part of nt triangles in C.  All edges in C have support of at least k-2.
      32             : // The total number of triangles in C is sum(C)/6.  C is returned as symmetric
      33             : // with a zero-free diagonal.
      34             : 
      35             : #define LG_FREE_ALL GrB_free (&C) ;
      36             : #include "LG_internal.h"
      37             : #include "LAGraphX.h"
      38             : 
      39             : //------------------------------------------------------------------------------
      40             : // LAGraph_KTruss: find the k-truss subgraph of a graph
      41             : //------------------------------------------------------------------------------
      42             : 
      43          84 : int LAGraph_KTruss              // compute the k-truss of a graph
      44             : (
      45             :     // outputs:
      46             :     GrB_Matrix *C_handle,       // output k-truss subgraph, C
      47             :     // inputs:
      48             :     LAGraph_Graph G,            // input graph
      49             :     uint32_t k,                 // find the k-truss, where k >= 3
      50             :     char *msg
      51             : )
      52             : {
      53             : 
      54             :     //--------------------------------------------------------------------------
      55             :     // check inputs
      56             :     //--------------------------------------------------------------------------
      57             : 
      58          84 :     LG_CLEAR_MSG ;
      59          84 :     GrB_Matrix C = NULL ;
      60          84 :     LG_ASSERT (C_handle != NULL, GrB_NULL_POINTER) ;
      61          83 :     (*C_handle) = NULL ;
      62          83 :     LG_ASSERT_MSG (k >= 3, GrB_INVALID_VALUE, "k invalid") ;
      63          82 :     LG_TRY (LAGraph_CheckGraph (G, msg)) ;
      64             : 
      65          81 :     if (G->kind == LAGraph_ADJACENCY_UNDIRECTED ||
      66           9 :        (G->kind == LAGraph_ADJACENCY_DIRECTED &&
      67           9 :         G->is_symmetric_structure == LAGraph_TRUE))
      68             :     {
      69             :         // the structure of A is known to be symmetric
      70             :         ;
      71             :     }
      72             :     else
      73             :     {
      74             :         // A is not known to be symmetric
      75           1 :         LG_ASSERT_MSG (false, -1005, "G->A must be symmetric") ;
      76             :     }
      77             : 
      78             :     // no self edges can be present
      79          80 :     LG_ASSERT_MSG (G->nself_edges == 0, -1004, "G->nself_edges must be zero") ;
      80             : 
      81             :     //--------------------------------------------------------------------------
      82             :     // initializations
      83             :     //--------------------------------------------------------------------------
      84             : 
      85             :     GrB_Index n ;
      86          79 :     GrB_Matrix S = G->A ;
      87          79 :     GRB_TRY (GrB_Matrix_nrows (&n, S)) ;
      88          79 :     GRB_TRY (GrB_Matrix_new (&C, GrB_UINT32, n, n)) ;
      89             :     GrB_Index nvals, nvals_last ;
      90          79 :     GRB_TRY (GrB_Matrix_nvals (&nvals_last, S)) ;
      91             : 
      92             :     //--------------------------------------------------------------------------
      93             :     // find the k-truss of G->A
      94             :     //--------------------------------------------------------------------------
      95             : 
      96             :     while (true)
      97             :     {
      98             :         // C{S} = S*S'
      99         327 :         GRB_TRY (GrB_mxm (C, S, NULL, LAGraph_plus_one_uint32, S, S,
     100             :             GrB_DESC_RST1)) ;
     101             :         // keep entries in C that are >= k-2
     102         327 :         GRB_TRY (GrB_select (C, NULL, NULL, GrB_VALUEGE_UINT32, C, k-2, NULL)) ;
     103             :         // return if the k-truss has been found
     104         327 :         GRB_TRY (GrB_Matrix_nvals (&nvals, C)) ;
     105         327 :         if (nvals == nvals_last)
     106             :         {
     107          79 :             (*C_handle) = C ;
     108          79 :             return (GrB_SUCCESS) ;
     109             :         }
     110             :         // advance to the next step
     111         248 :         nvals_last = nvals ;
     112         248 :         S = C ;
     113             :     }
     114             : }

Generated by: LCOV version 1.14