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

          Line data    Source code
       1             : //------------------------------------------------------------------------------
       2             : // LAGraph/src/test/test_PageRank.c: test cases for pagerank
       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             : #include <stdio.h>
      19             : #include <acutest.h>
      20             : 
      21             : #include <LAGraph_test.h>
      22             : 
      23             : #define LEN 512
      24             : char msg [LAGRAPH_MSG_LEN] ;
      25             : char filename [LEN+1] ;
      26             : LAGraph_Graph G = NULL ;
      27             : 
      28             : //------------------------------------------------------------------------------
      29             : // difference: compare the LAGraph and MATLAB results
      30             : //------------------------------------------------------------------------------
      31             : 
      32             : float difference (GrB_Vector centrality, double *matlab_result) ;
      33             : 
      34           6 : float difference (GrB_Vector centrality, double *matlab_result)
      35             : {
      36           6 :     GrB_Vector diff = NULL, cmatlab = NULL ;
      37           6 :     GrB_Index n = 0 ;
      38           6 :     OK (GrB_Vector_size (&n, centrality)) ;
      39           6 :     OK (GrB_Vector_new (&cmatlab, GrB_FP32, n)) ;
      40         228 :     for (int i = 0 ; i < n ; i++)
      41             :     {
      42         222 :         OK (GrB_Vector_setElement_FP64 (cmatlab, matlab_result [i], i)) ;
      43             :     }
      44             :     // diff = max (abs (cmatlab - centrality))
      45           6 :     OK (GrB_Vector_new (&diff, GrB_FP32, n)) ;
      46           6 :     OK (GrB_eWiseAdd (diff, NULL, NULL, GrB_MINUS_FP32, cmatlab, centrality,
      47             :         NULL)) ;
      48           6 :     OK (GrB_apply (diff, NULL, NULL, GrB_ABS_FP32, diff, NULL)) ;
      49           6 :     float err = 0 ;
      50           6 :     OK (GrB_reduce (&err, NULL, GrB_MAX_MONOID_FP32, diff, NULL)) ;
      51           6 :     OK (GrB_free (&diff)) ;
      52           6 :     OK (GrB_free (&cmatlab)) ;
      53           6 :     return (err) ;
      54             : }
      55             : 
      56             : //------------------------------------------------------------------------------
      57             : // valid results for karate graph and west0067 graphs
      58             : //------------------------------------------------------------------------------
      59             : 
      60             : // The first two matrices have no sinks (nodes with zero outdegree) so the
      61             : // MATLAB centrality (G, 'pagerank'), LAGraph_VertextCentrality_PageRankGAP,
      62             : // and LAGr_PageRank results will be essentially the same.
      63             : 
      64             : // MATLAB computes in double precision, while LAGraph_*PageRank* computes in
      65             : // single precision, so the difference will be about 1e-5 or so.
      66             : 
      67             : double karate_rank [34] = {
      68             :     0.0970011147,
      69             :     0.0528720584,
      70             :     0.0570750515,
      71             :     0.0358615175,
      72             :     0.0219857202,
      73             :     0.0291233505,
      74             :     0.0291233505,
      75             :     0.0244945048,
      76             :     0.0297681451,
      77             :     0.0143104668,
      78             :     0.0219857202,
      79             :     0.0095668739,
      80             :     0.0146475355,
      81             :     0.0295415677,
      82             :     0.0145381625,
      83             :     0.0145381625,
      84             :     0.0167900065,
      85             :     0.0145622041,
      86             :     0.0145381625,
      87             :     0.0196092670,
      88             :     0.0145381625,
      89             :     0.0145622041,
      90             :     0.0145381625,
      91             :     0.0315206825,
      92             :     0.0210719482,
      93             :     0.0210013837,
      94             :     0.0150430281,
      95             :     0.0256382216,
      96             :     0.0195723309,
      97             :     0.0262863139,
      98             :     0.0245921424,
      99             :     0.0371606178,
     100             :     0.0716632142,
     101             :     0.1008786453 } ;
     102             : 
     103             : double west0067_rank [67] = {
     104             :     0.0233753869,
     105             :     0.0139102552,
     106             :     0.0123441027,
     107             :     0.0145657095,
     108             :     0.0142018541,
     109             :     0.0100791606,
     110             :     0.0128753395,
     111             :     0.0143945684,
     112             :     0.0110203141,
     113             :     0.0110525383,
     114             :     0.0119311961,
     115             :     0.0072382247,
     116             :     0.0188680398,
     117             :     0.0141596605,
     118             :     0.0174877889,
     119             :     0.0170362099,
     120             :     0.0120433909,
     121             :     0.0219844489,
     122             :     0.0195274443,
     123             :     0.0394465722,
     124             :     0.0112038726,
     125             :     0.0090174094,
     126             :     0.0140088120,
     127             :     0.0122532937,
     128             :     0.0153346283,
     129             :     0.0135241334,
     130             :     0.0158714693,
     131             :     0.0149689529,
     132             :     0.0144097230,
     133             :     0.0137583019,
     134             :     0.0314386080,
     135             :     0.0092857745,
     136             :     0.0081814168,
     137             :     0.0102137827,
     138             :     0.0096547214,
     139             :     0.0129622400,
     140             :     0.0244173417,
     141             :     0.0173963657,
     142             :     0.0127705717,
     143             :     0.0143297446,
     144             :     0.0140509341,
     145             :     0.0104117131,
     146             :     0.0173516407,
     147             :     0.0149175105,
     148             :     0.0119979624,
     149             :     0.0095043613,
     150             :     0.0153295328,
     151             :     0.0077710930,
     152             :     0.0259969472,
     153             :     0.0126926269,
     154             :     0.0088870166,
     155             :     0.0080836101,
     156             :     0.0096023576,
     157             :     0.0091000837,
     158             :     0.0246131958,
     159             :     0.0159589365,
     160             :     0.0183500031,
     161             :     0.0155811507,
     162             :     0.0157693756,
     163             :     0.0116319823,
     164             :     0.0230649292,
     165             :     0.0149070613,
     166             :     0.0157469640,
     167             :     0.0134396036,
     168             :     0.0189218603,
     169             :     0.0114528518,
     170             :     0.0223213267 } ;
     171             : 
     172             : // ldbc-directed-example.mtx has two sinks: nodes 3 and 9
     173             : // its pagerank must be computed with LAGr_PageRank.
     174             : double ldbc_directed_example_rank [10] = {
     175             :     0.1697481823,
     176             :     0.0361514465,
     177             :     0.1673241104,
     178             :     0.1669092572,
     179             :     0.1540948145,
     180             :     0.0361514465,
     181             :     0.0361514465,
     182             :     0.1153655134,
     183             :     0.0361514465,
     184             :     0.0819523364 } ;
     185             : 
     186             : //------------------------------------------------------------------------------
     187             : // tesk_ranker
     188             : //------------------------------------------------------------------------------
     189             : 
     190           1 : void test_ranker(void)
     191             : {
     192           1 :     LAGraph_Init (msg) ;
     193           1 :     GrB_Matrix A = NULL ;
     194           1 :     GrB_Vector centrality = NULL, cmatlab = NULL, diff = NULL ;
     195           1 :     int niters = 0 ;
     196             : 
     197             :     //--------------------------------------------------------------------------
     198             :     // karate: no sinks
     199             :     //--------------------------------------------------------------------------
     200             : 
     201             :     // create the karate graph
     202           1 :     snprintf (filename, LEN, LG_DATA_DIR "%s", "karate.mtx") ;
     203           1 :     FILE *f = fopen (filename, "r") ;
     204           1 :     TEST_CHECK (f != NULL) ;
     205           1 :     OK (LAGraph_MMRead (&A, f, msg)) ;
     206           1 :     OK (fclose (f)) ;
     207           1 :     OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)) ;
     208           1 :     TEST_CHECK (A == NULL) ;    // A has been moved into G->A
     209           1 :     OK (LAGraph_Cached_OutDegree (G, msg)) ;
     210             : 
     211             :     // compute its pagerank using the GAP method
     212           1 :     OK (LAGr_PageRankGAP (&centrality, &niters, G, 0.85,
     213             :         1e-4, 100, msg)) ;
     214             : 
     215             :     // compare with MATLAB: cmatlab = centrality (G, 'pagerank')
     216           1 :     float err = difference (centrality, karate_rank) ;
     217           1 :     float rsum = 0 ;
     218           1 :     OK (GrB_reduce (&rsum, NULL, GrB_PLUS_MONOID_FP32, centrality, NULL)) ;
     219           1 :     printf ("\nkarate:   err: %e (GAP),      sum(r): %e iters: %d\n",
     220             :         err, rsum, niters) ;
     221           1 :     TEST_CHECK (err < 1e-4) ;
     222           1 :     OK (GrB_free (&centrality)) ;
     223             : 
     224             :     // compute its pagerank using the standard method
     225           1 :     OK (LAGr_PageRank (&centrality, &niters, G, 0.85, 1e-4, 100, msg)) ;
     226             : 
     227             :     // compare with MATLAB: cmatlab = centrality (G, 'pagerank')
     228           1 :     err = difference (centrality, karate_rank) ;
     229           1 :     OK (GrB_reduce (&rsum, NULL, GrB_PLUS_MONOID_FP32, centrality, NULL)) ;
     230           1 :     printf ("karate:   err: %e (standard), sum(r): %e iters: %d\n",
     231             :         err, rsum, niters) ;
     232           1 :     TEST_CHECK (err < 1e-4) ;
     233           1 :     OK (GrB_free (&centrality)) ;
     234             : 
     235             :     // test for failure to converge
     236           1 :     int status = LAGr_PageRank (&centrality, &niters, G, 0.85, 1e-4, 2, msg) ;
     237           1 :     printf ("status: %d msg: %s\n", status, msg) ;
     238           1 :     TEST_CHECK (status == LAGRAPH_CONVERGENCE_FAILURE) ;
     239             : 
     240           1 :     OK (LAGraph_Delete (&G, msg)) ;
     241             : 
     242             :     //--------------------------------------------------------------------------
     243             :     // west0067: no sinks
     244             :     //--------------------------------------------------------------------------
     245             : 
     246             :     // create the west0067 graph
     247           1 :     snprintf (filename, LEN, LG_DATA_DIR "%s", "west0067.mtx") ;
     248           1 :     f = fopen (filename, "r") ;
     249           1 :     TEST_CHECK (f != NULL) ;
     250           1 :     OK (LAGraph_MMRead (&A, f, msg)) ;
     251           1 :     OK (fclose (f)) ;
     252           1 :     OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
     253           1 :     TEST_CHECK (A == NULL) ;    // A has been moved into G->A
     254           1 :     OK (LAGraph_Cached_AT (G, msg)) ;
     255           1 :     OK (LAGraph_Cached_OutDegree (G, msg)) ;
     256             : 
     257             :     // compute its pagerank using the GAP method
     258           1 :     OK (LAGr_PageRankGAP (&centrality, &niters, G, 0.85,
     259             :         1e-4, 100, msg)) ;
     260             : 
     261             :     // compare with MATLAB: cmatlab = centrality (G, 'pagerank')
     262           1 :     err = difference (centrality, west0067_rank) ;
     263           1 :     OK (GrB_reduce (&rsum, NULL, GrB_PLUS_MONOID_FP32, centrality, NULL)) ;
     264           1 :     printf ("west0067: err: %e (GAP),      sum(r): %e iters: %d\n",
     265             :         err, rsum, niters) ;
     266           1 :     TEST_CHECK (err < 1e-4) ;
     267           1 :     OK (GrB_free (&centrality)) ;
     268             : 
     269             :     // compute its pagerank using the standard method
     270           1 :     OK (LAGr_PageRank (&centrality, &niters, G, 0.85, 1e-4, 100, msg)) ;
     271             : 
     272             :     // compare with MATLAB: cmatlab = centrality (G, 'pagerank')
     273           1 :     err = difference (centrality, west0067_rank) ;
     274           1 :     printf ("west0067: err: %e (standard), sum(r): %e iters: %d\n",
     275             :         err, rsum, niters) ;
     276           1 :     TEST_CHECK (err < 1e-4) ;
     277           1 :     OK (GrB_free (&centrality)) ;
     278             : 
     279           1 :     OK (LAGraph_Delete (&G, msg)) ;
     280             : 
     281             :     //--------------------------------------------------------------------------
     282             :     // ldbc-directed-example: has 2 sinks
     283             :     //--------------------------------------------------------------------------
     284             : 
     285             :     // create the ldbc-directed-example graph
     286           1 :     snprintf (filename, LEN, LG_DATA_DIR "%s", "ldbc-directed-example.mtx") ;
     287           1 :     f = fopen (filename, "r") ;
     288           1 :     TEST_CHECK (f != NULL) ;
     289           1 :     OK (LAGraph_MMRead (&A, f, msg)) ;
     290           1 :     OK (fclose (f)) ;
     291           1 :     OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
     292           1 :     TEST_CHECK (A == NULL) ;    // A has been moved into G->A
     293           1 :     OK (LAGraph_Cached_AT (G, msg)) ;
     294           1 :     OK (LAGraph_Cached_OutDegree (G, msg)) ;
     295             : 
     296           1 :     printf ("\n=========== ldbc-directed-example, with sink nodes 3 and 9:\n") ;
     297           1 :     OK (LAGraph_Graph_Print (G, LAGraph_COMPLETE, stdout, msg)) ;
     298             : 
     299             :     // compute its pagerank using the GAP method ("bleeds" rank)
     300           1 :     OK (LAGr_PageRankGAP (&centrality, &niters, G, 0.85,
     301             :         1e-4, 100, msg)) ;
     302           1 :     err = difference (centrality, ldbc_directed_example_rank) ;
     303           1 :     OK (GrB_reduce (&rsum, NULL, GrB_PLUS_MONOID_FP32, centrality, NULL)) ;
     304           1 :     printf ("\nGAP-style page rank is expected to be wrong:\n") ;
     305           1 :     printf ("ldbc-directed: err: %e (GAP), sum(r): %e, niters %d\n",
     306             :         err, rsum, niters) ;
     307           1 :     printf ("The GAP pagerank is incorrect for this method:\n") ;
     308           1 :     OK (LAGraph_Vector_Print (centrality, LAGraph_COMPLETE, stdout, msg)) ;
     309           1 :     OK (GrB_free (&centrality)) ;
     310             : 
     311             :     // compute its pagerank using the standard method
     312           1 :     OK (LAGr_PageRank (&centrality, &niters, G, 0.85, 1e-4, 100, msg)) ;
     313             : 
     314             :     // compare with MATLAB: cmatlab = centrality (G, 'pagerank')
     315           1 :     err = difference (centrality, ldbc_directed_example_rank) ;
     316           1 :     OK (GrB_reduce (&rsum, NULL, GrB_PLUS_MONOID_FP32, centrality, NULL)) ;
     317           1 :     printf ("\nwith sinks handled properly:\n") ;
     318           1 :     printf ("ldbc-directed: err: %e (standard), sum(r): %e, niters %d\n",
     319             :         err, rsum, niters) ;
     320           1 :     TEST_CHECK (err < 1e-4) ;
     321           1 :     printf ("This is the correct pagerank, with sinks handled properly:\n") ;
     322           1 :     OK (LAGraph_Vector_Print (centrality, LAGraph_COMPLETE, stdout, msg)) ;
     323           1 :     OK (GrB_free (&centrality)) ;
     324             : 
     325           1 :     OK (LAGraph_Delete (&G, msg)) ;
     326             : 
     327             :     //--------------------------------------------------------------------------
     328             : 
     329           1 :     LAGraph_Finalize (msg) ;
     330           1 : }
     331             : 
     332             : //------------------------------------------------------------------------------
     333             : // list of tests
     334             : //------------------------------------------------------------------------------
     335             : 
     336             : TEST_LIST = {
     337             :     {"test_ranker", test_ranker},
     338             :     {NULL, NULL}
     339             : };

Generated by: LCOV version 1.14