LCOV - code coverage report
Current view: top level - experimental/test - test_RichClubCoefficient.c (source / functions) Hit Total Coverage
Test: LAGraph code coverage report. Commit id: 7b9d2ee. Current time (UTC): 2025-06-03T21:57:17Z Lines: 143 143 100.0 %
Date: 2025-06-03 22:02:40 Functions: 4 4 100.0 %

          Line data    Source code
       1             : //----------------------------------------------------------------------------
       2             : // LAGraph/src/test/test_RichClubCoefficient.c: test cases for 
       3             : // LAGraph_RichClubCoefficient
       4             : //----------------------------------------------------------------------------
       5             : 
       6             : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
       7             : // SPDX-License-Identifier: BSD-2-Clause
       8             : //
       9             : // For additional details (including references to third party source code and
      10             : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
      11             : // Contributors.txt for a full list of contributors. Created, in part, with
      12             : // funding and support from the U.S. Government (see Acknowledgments.txt file).
      13             : // DM22-0790
      14             : 
      15             : //-----------------------------------------------------------------------------
      16             : 
      17             : // This program tests Rich Club Coefficient by comparing it to know values.
      18             : 
      19             : #include <stdio.h>
      20             : #include <acutest.h>
      21             : #include <LAGraphX.h>
      22             : #include <LAGraph_test.h>
      23             : #include <LG_Xtest.h>
      24             : #include <LG_test.h>
      25             : 
      26             : char msg [LAGRAPH_MSG_LEN] ;
      27             : 
      28             : GrB_Matrix A = NULL, C = NULL;
      29             : GrB_Vector rcc = NULL, check_rcc = NULL ;
      30             : LAGraph_Graph G = NULL ;
      31             : 
      32             : #define LEN 512
      33             : char filename [LEN+1] ;
      34             : typedef struct
      35             : {
      36             :     double *rcc ; // for unweighted matchings, the size of the matching. For weighted, sum of edge weights
      37             :     uint64_t n;
      38             :     const char *name ;    // matrix file name
      39             : }
      40             : matrix_info ;
      41             : 
      42             : double rcc1[] = {0.08489795918367347, 0.09042553191489362, 0.11806543385490754,
      43             : 0.15270935960591134, 0.17543859649122806, 0.18681318681318682,
      44             : 0.3333333333333333, 0.3333333333333333};
      45             : 
      46             : double rcc2[] = {0.048040201005025124, 0.048040201005025124,
      47             : 0.04842393787117405, 0.04945054945054945, 0.05129490392648287,
      48             : 0.052702702702702706, 0.05523809523809524, 0.0613164184592756,
      49             : 0.06755555555555555, 0.07603960396039604, 0.08637747336377473,
      50             : 0.09183673469387756, 0.09090909090909091, 0.11578947368421053,
      51             : 0.15555555555555556, 0.16666666666666666, 0.0};
      52             : 
      53             : double rcc3[] = {0.020418922066450775, 0.020418922066450775,
      54             : 0.020418922066450775, 0.020418922066450775, 0.020683173955750592,
      55             : 0.02150664338158559, 0.02150664338158559, 0.02150664338158559,
      56             : 0.02150664338158559, 0.021543516982986302, 0.02175414105479627,
      57             : 0.02177185436416472, 0.0218052051134787, 0.021857560922981484,
      58             : 0.02201878369318151, 0.022188402920223206, 0.022804582640104137,
      59             : 0.02498473901586159, 0.025249731948717845, 0.02596385205080857,
      60             : 0.027247042660294644, 0.027751420992800303, 0.028748882924051613,
      61             : 0.030170594138205473, 0.031102722135686933, 0.03269071555292726,
      62             : 0.03991334958028703, 0.04169452474008947, 0.04259653806582863,
      63             : 0.044304609453855226, 0.04526841567726286, 0.04650692548781721,
      64             : 0.049532888465204955, 0.05002586270597798, 0.05063092496587295,
      65             : 0.05300441583096034, 0.054629398879867785, 0.05653826181371855,
      66             : 0.059291297964366496, 0.06080825884426539, 0.06422637670884515,
      67             : 0.06768885564697083, 0.06889041561605802, 0.0701751819478477,
      68             : 0.07607985994153141, 0.07831153079788616, 0.07894806048652203,
      69             : 0.08038113301271196, 0.08207037795568796, 0.0836966039974926,
      70             : 0.08430976691170078, 0.08589112981595826, 0.08725832508207827,
      71             : 0.10235720633666719, 0.10276089969086451, 0.10358862936809705,
      72             : 0.10741510741510742, 0.1110049401354954, 0.11278770872986284,
      73             : 0.11678584477269169, 0.11817043607981033, 0.12116372726010276,
      74             : 0.1218450408924313, 0.12440239209741634, 0.12798272259582463,
      75             : 0.13977635782747605, 0.14573643410852713, 0.14652869744786873,
      76             : 0.1486150774302895, 0.15837726930369062, 0.158866930171278,
      77             : 0.16537043438184124, 0.16662279547249276, 0.1688366106970758,
      78             : 0.17170333945410973, 0.17634190936398067, 0.17711727724564694,
      79             : 0.17787300615583443, 0.1779243342906783, 0.17813492063492065,
      80             : 0.16556371804990588, 0.16556371804990588, 0.16556371804990588,
      81             : 0.16556371804990588, 0.16729064039408867, 0.1701346389228886,
      82             : 0.1989280560709132, 0.20149602618045817, 0.20475808607324245,
      83             : 0.16666666666666666, 0.16840882694541232, 0.17894736842105263,
      84             : 0.16666666666666666, 1.0} ;
      85             : double rcc4[] = {0.0016506547800326698, 0.0017226315730560155, 
      86             :     0.0034201182512489416, 0.0037033309852068028, 0.05405405405405406};
      87             : const matrix_info tests [ ] =
      88             : {
      89             :     {rcc1, sizeof(rcc1) / sizeof(rcc1[0]), "random_unweighted_general1.mtx"},
      90             :     {rcc2, sizeof(rcc2) / sizeof(rcc2[0]), "random_unweighted_general2.mtx"},
      91             :     {rcc3, sizeof(rcc3) / sizeof(rcc3[0]), "bcsstk13.mtx"},
      92             :     {rcc4, sizeof(rcc4) / sizeof(rcc4[0]), "test_FW_2500.mtx"},
      93             :     {NULL, 0, ""}
      94             : } ;
      95             : 
      96             : const char *tests2 [ ] =
      97             : {
      98             :     "random_unweighted_general1.mtx",
      99             :     "random_unweighted_general2.mtx",
     100             :     "bcsstk13.mtx",
     101             :     "bcsstk13_celeb.mtx",
     102             :     "test_FW_1000.mtx",
     103             :     "test_FW_2003.mtx",
     104             :     "test_FW_2500.mtx",
     105             :     ""
     106             : } ;
     107             : 
     108           1 : void test_RichClubCoefficient (void)
     109             : {
     110             :     //--------------------------------------------------------------------------
     111             :     // start LAGraph
     112             :     //--------------------------------------------------------------------------
     113           1 :     OK (LAGraph_Init (msg)) ;
     114             :     
     115             : 
     116           1 :     for (int k = 0 ; ; k++)
     117           4 :     {
     118             :         //The following code taken from MIS tester
     119             :         // load the matrix as A
     120           5 :         const char *aname = tests [k].name;
     121           5 :         if (strlen (aname) == 0) break;
     122           4 :         TEST_CASE (aname) ;
     123           4 :         snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
     124           4 :         FILE *f = fopen (filename, "r") ;
     125           4 :         TEST_CHECK (f != NULL) ;
     126           4 :         OK (LAGraph_MMRead (&A, f, msg)) ;
     127           4 :         OK (fclose (f)) ;
     128           4 :         TEST_MSG ("Loading of valued matrix failed") ;
     129           4 :         printf ("\nMatrix: %s\n", aname) ;
     130           4 :         const double *ans = tests [k].rcc;
     131           4 :         const uint64_t n_ans = tests [k].n;
     132             : 
     133             :         // C = structure of A
     134           4 :         OK (LAGraph_Matrix_Structure (&C, A, msg)) ;
     135           4 :         OK (GrB_free (&A)) ;
     136             : 
     137             :         // construct a directed graph G with adjacency matrix C
     138           4 :         OK (LAGraph_New (&G, &C, LAGraph_ADJACENCY_DIRECTED, msg)) ;
     139           4 :         TEST_CHECK (C == NULL) ;
     140             : 
     141             :         // check if the pattern is symmetric
     142           4 :         OK (LAGraph_Cached_IsSymmetricStructure (G, msg)) ;
     143             : 
     144           4 :         if (G->is_symmetric_structure == LAGraph_FALSE)
     145             :         {
     146             :             // make the adjacency matrix symmetric
     147           1 :             OK (LAGraph_Cached_AT (G, msg)) ;
     148           1 :             OK (GrB_eWiseAdd (G->A, NULL, NULL, GrB_LOR, G->A, G->AT, NULL)) ;
     149           1 :             G->is_symmetric_structure = LAGraph_TRUE ;
     150             :         }
     151           4 :         G->kind = LAGraph_ADJACENCY_UNDIRECTED ;
     152             : 
     153             :         // check for self-edges
     154           4 :         OK (LAGraph_Cached_NSelfEdges (G, msg)) ;
     155           4 :         if (G->nself_edges != 0)
     156             :         {
     157             :             // remove self-edges
     158           2 :             printf ("graph has %g self edges\n", (double) G->nself_edges) ;
     159           2 :             OK (LAGraph_DeleteSelfEdges (G, msg)) ;
     160           2 :             printf ("now has %g self edges\n", (double) G->nself_edges) ;
     161           2 :             TEST_CHECK (G->nself_edges == 0) ;
     162             :         }
     163             : 
     164             :         // compute the row degree
     165           4 :         OK (LAGraph_Cached_OutDegree (G, msg)) ;
     166             : 
     167             :         //----------------------------------------------------------------------
     168             :         // test the algorithm
     169             :         //----------------------------------------------------------------------
     170             : 
     171           4 :         printf ("RCC computation begins:\n") ;
     172           4 :         GrB_set (GrB_GLOBAL, (int32_t) (true), GxB_BURBLE) ;
     173           4 :         OK(LAGraph_RichClubCoefficient ( &rcc, G, msg));
     174           4 :         printf("%s\n", msg);
     175           4 :         GrB_set (GrB_GLOBAL, (int32_t) (false), GxB_BURBLE) ;
     176           4 :         printf ("RCC computation ends:\n") ;
     177             : 
     178             :         //----------------------------------------------------------------------
     179             :         // check results
     180             :         //----------------------------------------------------------------------
     181           4 :         double comp_val = 0;
     182         128 :         for(int64_t i = n_ans - 1; i >= 0; --i)
     183             :         {
     184         124 :             GrB_Vector_extractElement(&comp_val, rcc, i) ;
     185         124 :             TEST_CHECK (
     186             :                 comp_val - ans[i] <= 1e-10 && ans[i] - comp_val <= 1e-10) ;
     187             :         }
     188           4 :         GxB_Vector_fprint (rcc, "rcc", GxB_SHORT, stdout);
     189           4 :         OK (GrB_free (&rcc)) ;
     190           4 :         OK (LAGraph_Delete (&G, msg)) ;
     191             :     }
     192             : 
     193             :     //--------------------------------------------------------------------------
     194             :     // free everything and finalize LAGraph
     195             :     //--------------------------------------------------------------------------
     196           1 :     OK (LAGraph_Finalize (msg)) ;
     197           1 : }
     198             : 
     199        1997 : void iseq(bool *z, const double *x, const double *y)
     200             : {
     201        1997 :     (*z) = (isnan(*x) && isnan(*y)) ||*x == *y ;
     202        1997 : }
     203             : //------------------------------------------------------------------------------
     204             : // test RichClubCoefficient vs C code
     205             : //------------------------------------------------------------------------------
     206           1 : void test_RCC_Check (void)
     207             : {
     208             :     //--------------------------------------------------------------------------
     209             :     // start LAGraph
     210             :     //--------------------------------------------------------------------------
     211           1 :     OK (LAGraph_Init (msg)) ;
     212           1 :     GrB_BinaryOp iseqFP = NULL ;
     213           1 :     OK (GrB_BinaryOp_new (
     214             :         &iseqFP, (GxB_binary_function) iseq, GrB_BOOL, GrB_FP64, GrB_FP64)) ;
     215             :     // OK (GxB_BinaryOp_new (
     216             :     //     &iseqFP, (GxB_binary_function) iseq, 
     217             :     //     GrB_BOOL, GrB_FP64, GrB_FP64, "iseq", ISEQ)) ;
     218           1 :     for (int k = 0 ; ; k++)
     219           7 :     {
     220             :         //The following code taken from MIS tester
     221             :         // load the matrix as A
     222           8 :         const char *aname = tests2 [k];
     223           8 :         if (strlen (aname) == 0) break;
     224           7 :         TEST_CASE (aname) ;
     225           7 :         snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
     226           7 :         FILE *f = fopen (filename, "r") ;
     227           7 :         TEST_CHECK (f != NULL) ;
     228           7 :         OK (LAGraph_MMRead (&A, f, msg)) ;
     229           7 :         OK (fclose (f)) ;
     230           7 :         TEST_MSG ("Loading of valued matrix failed") ;
     231           7 :         printf ("\nMatrix: %s\n", aname) ;
     232             : 
     233             :         // C = structure of A
     234           7 :         OK (LAGraph_Matrix_Structure (&C, A, msg)) ;
     235           7 :         OK (GrB_free (&A)) ;
     236             : 
     237             :         // construct a directed graph G with adjacency matrix C
     238           7 :         OK (LAGraph_New (&G, &C, LAGraph_ADJACENCY_DIRECTED, msg)) ;
     239           7 :         TEST_CHECK (C == NULL) ;
     240             : 
     241             :         // check if the pattern is symmetric
     242           7 :         OK (LAGraph_Cached_IsSymmetricStructure (G, msg)) ;
     243             : 
     244           7 :         if (G->is_symmetric_structure == LAGraph_FALSE)
     245             :         {
     246             :             // make the adjacency matrix symmetric
     247           2 :             OK (LAGraph_Cached_AT (G, msg)) ;
     248           2 :             OK (GrB_eWiseAdd (G->A, NULL, NULL, GrB_LOR, G->A, G->AT, NULL)) ;
     249           2 :             G->is_symmetric_structure = LAGraph_TRUE ;
     250             :         }
     251           7 :         G->kind = LAGraph_ADJACENCY_UNDIRECTED ;
     252             : 
     253             :         // check for self-edges
     254           7 :         OK (LAGraph_Cached_NSelfEdges (G, msg)) ;
     255           7 :         if (G->nself_edges != 0)
     256             :         {
     257             :             // remove self-edges
     258           5 :             printf ("graph has %g self edges\n", (double) G->nself_edges) ;
     259           5 :             OK (LAGraph_DeleteSelfEdges (G, msg)) ;
     260           5 :             printf ("now has %g self edges\n", (double) G->nself_edges) ;
     261           5 :             TEST_CHECK (G->nself_edges == 0) ;
     262             :         }
     263             : 
     264             :         // compute the row degree
     265           7 :         OK (LAGraph_Cached_OutDegree (G, msg)) ;
     266             : 
     267             :         //----------------------------------------------------------------------
     268             :         // test the algorithm
     269             :         //----------------------------------------------------------------------
     270             : 
     271             :         // GrB_set (GrB_GLOBAL, (int32_t) (true), GxB_BURBLE) ;
     272           7 :         OK(LAGraph_RichClubCoefficient ( &rcc, G, msg));
     273             :         // GrB_set (GrB_GLOBAL, (int32_t) (false), GxB_BURBLE) ;
     274             : 
     275           7 :         OK(LG_check_rcc(&check_rcc, G, msg));
     276             :         //----------------------------------------------------------------------
     277             :         // check results
     278             :         //----------------------------------------------------------------------
     279           7 :         bool flag = false;
     280           7 :         OK (LAGraph_Vector_IsEqualOp(&flag, rcc, check_rcc, iseqFP, msg)) ;
     281           7 :         TEST_CHECK (flag) ;
     282           7 :         GxB_Vector_fprint (rcc, "rcc", GxB_SHORT, stdout);
     283           7 :         GxB_Vector_fprint (check_rcc, "check_rcc", GxB_SHORT, stdout);
     284           7 :         OK (GrB_free (&rcc)) ;
     285           7 :         OK (GrB_free (&check_rcc)) ;
     286           7 :         OK (LAGraph_Delete (&G, msg)) ;
     287             :     }
     288             : 
     289             :     //--------------------------------------------------------------------------
     290             :     // free everything and finalize LAGraph
     291             :     //--------------------------------------------------------------------------
     292           1 :     OK (GrB_free (&iseqFP)) ;
     293           1 :     OK (LAGraph_Finalize (msg)) ;
     294           1 : }
     295             : //------------------------------------------------------------------------------
     296             : // test_RCC_brutal:
     297             : //------------------------------------------------------------------------------
     298             : 
     299             : #if LAGRAPH_SUITESPARSE
     300           1 : void test_rcc_brutal (void)
     301             : {
     302             :     //--------------------------------------------------------------------------
     303             :     // start LAGraph
     304             :     //--------------------------------------------------------------------------
     305           1 :     OK (LG_brutal_setup (msg)) ;
     306             :     
     307             : 
     308           1 :     for (int k = 0 ; ; k++)
     309           4 :     {
     310             :         // load the matrix as A
     311           5 :         const char *aname = tests [k].name;
     312           5 :         if (strlen (aname) == 0) break;
     313           4 :         TEST_CASE (aname) ;
     314           4 :         snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
     315           4 :         FILE *f = fopen (filename, "r") ;
     316           4 :         TEST_CHECK (f != NULL) ;
     317           4 :         OK (LAGraph_MMRead (&A, f, msg)) ;
     318           4 :         OK (fclose (f)) ;
     319           4 :         TEST_MSG ("Loading of valued matrix failed") ;
     320           4 :         printf ("\nMatrix: %s\n", aname) ;
     321           4 :         const double *ans = tests [k].rcc;
     322           4 :         const uint64_t n_ans = tests [k].n;
     323             : 
     324             :         // C = structure of A
     325           4 :         OK (LAGraph_Matrix_Structure (&C, A, msg)) ;
     326           4 :         OK (GrB_free (&A)) ;
     327             : 
     328             :         // construct a directed graph G with adjacency matrix C
     329           4 :         OK (LAGraph_New (&G, &C, LAGraph_ADJACENCY_DIRECTED, msg)) ;
     330           4 :         TEST_CHECK (C == NULL) ;
     331             : 
     332             :         // check if the pattern is symmetric
     333           4 :         OK (LAGraph_Cached_IsSymmetricStructure (G, msg)) ;
     334             : 
     335           4 :         if (G->is_symmetric_structure == LAGraph_FALSE)
     336             :         {
     337             :             // make the adjacency matrix symmetric
     338           1 :             OK (LAGraph_Cached_AT (G, msg)) ;
     339           1 :             OK (GrB_eWiseAdd (G->A, NULL, NULL, GrB_LOR, G->A, G->AT, NULL)) ;
     340           1 :             G->is_symmetric_structure = LAGraph_TRUE ;
     341             :         }
     342           4 :         G->kind = LAGraph_ADJACENCY_UNDIRECTED ;
     343             : 
     344             :         // check for self-edges
     345           4 :         OK (LAGraph_Cached_NSelfEdges (G, msg)) ;
     346           4 :         if (G->nself_edges != 0)
     347             :         {
     348             :             // remove self-edges
     349           2 :             printf ("graph has %g self edges\n", (double) G->nself_edges) ;
     350           2 :             OK (LAGraph_DeleteSelfEdges (G, msg)) ;
     351           2 :             printf ("now has %g self edges\n", (double) G->nself_edges) ;
     352           2 :             TEST_CHECK (G->nself_edges == 0) ;
     353             :         }
     354             : 
     355             :         // compute the row degree
     356           4 :         OK (LAGraph_Cached_OutDegree (G, msg)) ;
     357             : 
     358           4 :         LG_BRUTAL_BURBLE (LAGraph_CheckGraph (G, msg)) ;
     359             :         //----------------------------------------------------------------------
     360             :         // test the algorithm
     361             :         //----------------------------------------------------------------------
     362             : 
     363           4 :         printf ("RCC computation begins:\n") ;
     364             :         // GrB_set (GrB_GLOBAL, (int32_t) (true), GxB_BURBLE) ;
     365         391 :         LG_BRUTAL_BURBLE (LAGraph_RichClubCoefficient( &rcc, G, msg));
     366           4 :         printf("%s\n", msg);
     367             :         // GrB_set (GrB_GLOBAL, (int32_t) (false), GxB_BURBLE) ;
     368           4 :         printf ("RCC computation ends:\n") ;
     369             : 
     370             :         //----------------------------------------------------------------------
     371             :         // check results
     372             :         //----------------------------------------------------------------------
     373           4 :         double comp_val = 0;
     374         128 :         for(int64_t i = n_ans - 1; i >= 0; --i)
     375             :         {
     376         124 :             OK (GrB_Vector_extractElement(&comp_val, rcc, i)) ;
     377         124 :             TEST_CHECK (fabs(comp_val - ans[i]) <= 1e-15) ;
     378             :         }
     379           4 :         OK (GrB_free (&rcc)) ;
     380           4 :         OK (LAGraph_Delete (&G, msg)) ;
     381             :     }
     382             : 
     383             :     //--------------------------------------------------------------------------
     384             :     // free everything and finalize LAGraph
     385             :     //--------------------------------------------------------------------------
     386           1 :     OK(LG_brutal_teardown(msg)) ;
     387           1 : }
     388             : #endif
     389             : 
     390             : //----------------------------------------------------------------------------
     391             : // the make program is created by acutest, and it runs a list of tests:
     392             : //----------------------------------------------------------------------------
     393             : 
     394             : TEST_LIST =
     395             : {
     396             :     {"RichClubCoefficient", test_RichClubCoefficient},
     397             :     #if LG_SUITESPARSE_GRAPHBLAS_V10
     398             :     {"RichClubCoefficient_Check", test_RCC_Check},
     399             :     #endif
     400             :     #if LAGRAPH_SUITESPARSE
     401             :     {"rcc_brutal", test_rcc_brutal},
     402             :     #endif
     403             :     {NULL, NULL}
     404             : } ;

Generated by: LCOV version 1.14