diff --git a/data/A_cluster.mtx b/data/A_cluster.mtx new file mode 100644 index 0000000000..2e4037055b --- /dev/null +++ b/data/A_cluster.mtx @@ -0,0 +1,10 @@ +%%MatrixMarket matrix array integer general +%%GraphBLAS type int64_t +7 1 7 +0 +0 +0 +0 +0 +0 +0 diff --git a/data/bcsstk13_cluster.mtx b/data/bcsstk13_cluster.mtx new file mode 100644 index 0000000000..21af660bc8 --- /dev/null +++ b/data/bcsstk13_cluster.mtx @@ -0,0 +1,2006 @@ +%%MatrixMarket matrix array integer general +%%GraphBLAS type int64_t +2003 1 2003 +42 +43 +2 +45 +4 +42 +6 +30 +8 +39 +10 +30 +12 +102 +14 +126 +16 +30 +6 +30 +22 +21 +10 +29 +102 +103 +26 +27 +28 +102 +30 +31 +32 +33 +22 +30 +36 +37 +169 +39 +10 +36 +42 +43 +44 +45 +4 +47 +36 +37 +50 +39 +52 +48 +42 +43 +56 +57 +58 +37 +1048 +63 +62 +63 +64 +63 +1008 +1058 +1058 +57 +70 +1048 +1008 +1019 +1019 +57 +76 +1006 +1048 +1032 +80 +63 +82 +1032 +1048 +63 +92 +87 +94 +1058 +102 +103 +94 +93 +88 +1058 +30 +31 +87 +33 +118 +96 +102 +103 +104 +105 +28 +107 +1048 +1032 +94 +87 +82 +1058 +126 +127 +118 +93 +94 +1058 +120 +121 +118 +123 +1017 +108 +126 +127 +128 +129 +28 +72 +120 +121 +134 +123 +22 +120 +126 +127 +140 +27 +28 +126 +156 +126 +28 +21 +160 +120 +150 +126 +152 +1082 +154 +132 +156 +126 +158 +171 +160 +126 +174 +175 +164 +177 +4 +174 +168 +169 +175 +171 +10 +168 +174 +175 +181 +177 +4 +174 +168 +169 +182 +171 +52 +175 +174 +175 +188 +57 +58 +169 +210 +425 +194 +195 +196 +359 +198 +295 +200 +277 +328 +295 +198 +211 +206 +213 +663 +663 +210 +211 +212 +213 +328 +323 +288 +703 +218 +261 +663 +247 +246 +213 +224 +211 +226 +247 +240 +261 +230 +213 +334 +277 +246 +329 +236 +267 +238 +365 +240 +460 +242 +277 +244 +460 +246 +247 +248 +247 +250 +247 +252 +460 +254 +460 +340 +295 +264 +425 +260 +261 +262 +371 +264 +265 +266 +267 +488 +353 +252 +271 +272 +277 +560 +460 +288 +460 +247 +277 +560 +247 +282 +460 +284 +247 +286 +267 +288 +195 +290 +460 +292 +295 +240 +295 +247 +247 +1798 +460 +288 +721 +431 +436 +1625 +442 +282 +277 +308 +195 +310 +277 +312 +313 +314 +213 +671 +422 +318 +213 +320 +633 +425 +323 +312 +261 +326 +195 +328 +329 +330 +267 +332 +668 +334 +335 +342 +261 +338 +261 +340 +341 +342 +343 +344 +267 +389 +347 +348 +391 +350 +479 +479 +353 +318 +213 +356 +380 +196 +359 +360 +668 +362 +425 +238 +365 +348 +391 +368 +380 +262 +371 +482 +373 +374 +387 +566 +566 +488 +379 +380 +381 +488 +395 +479 +479 +380 +387 +395 +389 +396 +479 +479 +393 +340 +395 +396 +479 +668 +380 +340 +401 +495 +479 +668 +334 +406 +583 +668 +195 +668 +406 +583 +668 +414 +668 +416 +425 +425 +425 +420 +653 +422 +653 +425 +425 +426 +196 +416 +671 +431 +431 +420 +657 +657 +657 +436 +431 +438 +657 +669 +657 +442 +431 +444 +1767 +444 +566 +277 +479 +450 +566 +277 +566 +526 +374 +456 +1803 +607 +607 +460 +454 +462 +607 +560 +1894 +460 +561 +468 +560 +454 +607 +472 +479 +486 +560 +566 +494 +478 +479 +480 +566 +482 +552 +484 +479 +486 +552 +488 +531 +479 +380 +479 +546 +494 +495 +479 +497 +393 +552 +500 +501 +479 +503 +510 +505 +506 +454 +508 +460 +510 +500 +500 +460 +514 +454 +460 +566 +454 +566 +454 +521 +460 +566 +561 +566 +526 +527 +561 +566 +454 +531 +391 +479 +425 +546 +495 +613 +538 +213 +552 +541 +501 +551 +544 +551 +546 +547 +454 +551 +562 +551 +552 +541 +460 +454 +556 +454 +546 +526 +560 +561 +562 +561 +564 +561 +566 +454 +568 +561 +570 +510 +572 +531 +657 +657 +587 +577 +213 +579 +657 +593 +582 +583 +510 +585 +510 +587 +588 +560 +641 +591 +510 +593 +582 +601 +657 +597 +663 +587 +460 +601 +454 +603 +460 +605 +454 +607 +551 +609 +454 +611 +526 +613 +583 +633 +425 +425 +618 +583 +620 +414 +668 +623 +618 +613 +626 +213 +658 +629 +613 +583 +668 +633 +640 +635 +642 +657 +638 +657 +640 +641 +642 +425 +644 +663 +646 +647 +658 +668 +668 +651 +658 +653 +660 +657 +660 +657 +658 +629 +660 +425 +662 +663 +623 +623 +635 +211 +668 +669 +657 +671 +678 +526 +660 +657 +640 +526 +678 +431 +680 +663 +657 +663 +444 +211 +668 +651 +663 +657 +560 +663 +692 +703 +694 +561 +657 +436 +698 +436 +657 +657 +438 +703 +668 +705 +663 +660 +566 +460 +710 +551 +712 +460 +657 +442 +716 +510 +566 +657 +444 +721 +431 +723 +444 +663 +1614 +727 +431 +510 +1625 +1767 +1734 +733 +551 +438 +1767 +657 +657 +727 +668 +551 +551 +669 +607 +733 +698 +436 +510 +526 +288 +733 +218 +261 +1679 +295 +282 +267 +224 +1805 +1814 +267 +566 +510 +692 +526 +710 +510 +288 +277 +242 +267 +1814 +277 +1679 +247 +248 +277 +1805 +247 +1894 +277 +248 +247 +295 +247 +1705 +247 +247 +460 +460 +1803 +607 +460 +603 +510 +710 +460 +566 +561 +562 +460 +1862 +561 +607 +295 +561 +561 +1744 +561 +1927 +460 +247 +460 +1803 +566 +566 +817 +460 +1744 +566 +566 +822 +822 +824 +861 +861 +827 +1048 +829 +858 +1008 +822 +1008 +824 +861 +1048 +1008 +1048 +839 +840 +827 +1008 +865 +844 +1419 +827 +847 +840 +855 +1386 +1419 +858 +858 +868 +855 +871 +868 +858 +874 +871 +861 +1386 +1419 +864 +865 +844 +868 +868 +871 +868 +871 +874 +871 +874 +891 +1008 +1008 +1008 +840 +1048 +874 +882 +891 +884 +1048 +1048 +1184 +888 +844 +1048 +891 +1048 +874 +894 +1480 +902 +855 +1442 +899 +1082 +855 +902 +858 +915 +905 +861 +918 +908 +1374 +902 +867 +912 +914 +914 +915 +916 +868 +918 +919 +902 +921 +1008 +923 +1008 +921 +926 +1008 +934 +1008 +1048 +931 +1006 +1008 +934 +1008 +905 +937 +1048 +1008 +1048 +1048 +1006 +1480 +950 +1480 +914 +947 +915 +868 +950 +871 +1082 +953 +874 +1080 +956 +1480 +964 +1480 +1081 +899 +980 +1097 +964 +1093 +1095 +967 +1073 +1008 +970 +977 +1097 +1097 +1093 +1093 +977 +977 +980 +1097 +980 +981 +981 +983 +1073 +1073 +988 +1093 +988 +989 +1532 +991 +1532 +1061 +981 +1019 +983 +1017 +1061 +1048 +1048 +92 +1008 +931 +1019 +1048 +1006 +1058 +1008 +1048 +1006 +1011 +1061 +1008 +1008 +1017 +1019 +1017 +1008 +1019 +1058 +1058 +1019 +1532 +1019 +1008 +1032 +1032 +1006 +1029 +923 +1048 +1032 +1006 +1032 +1019 +1008 +1008 +1048 +953 +1040 +1041 +1048 +1043 +1073 +1008 +1046 +1058 +1048 +1008 +1008 +1048 +1008 +1048 +94 +1048 +1019 +1532 +1058 +1017 +1019 +1061 +1058 +1008 +1008 +1285 +1019 +1058 +1058 +1061 +1532 +988 +977 +1073 +989 +1058 +1285 +1532 +1078 +977 +1080 +1081 +1082 +1083 +1081 +867 +864 +1316 +1093 +1095 +1090 +980 +980 +1093 +1097 +1095 +977 +1097 +977 +977 +1291 +1073 +1083 +914 +977 +1105 +1097 +977 +977 +1109 +988 +1093 +1112 +1227 +1430 +1115 +1216 +1430 +1112 +1160 +956 +1115 +1097 +970 +1522 +1097 +1522 +1532 +1097 +1129 +1061 +1285 +1532 +1048 +1134 +1532 +1322 +1532 +1532 +1532 +1532 +1532 +1277 +1285 +1008 +1061 +1019 +1019 +1532 +1017 +1532 +1532 +1058 +1008 +1532 +1048 +1285 +1019 +1158 +1479 +1160 +1479 +1011 +1329 +1006 +1329 +1058 +1167 +934 +1169 +923 +1171 +1462 +926 +1008 +923 +1032 +923 +1178 +1032 +1158 +884 +884 +1008 +1048 +1382 +840 +874 +1432 +882 +891 +822 +1192 +1008 +1160 +861 +1419 +1386 +1198 +861 +861 +1386 +1419 +1192 +858 +874 +858 +1115 +1427 +855 +1419 +1419 +1442 +1442 +1382 +871 +1216 +1219 +1451 +1219 +1442 +1480 +1442 +1480 +915 +1225 +1373 +1227 +950 +1488 +1230 +1490 +1480 +1490 +1480 +1387 +1236 +1388 +1216 +964 +1501 +1093 +977 +1511 +1219 +1498 +1097 +1503 +1480 +1498 +1291 +1372 +1225 +1293 +1097 +1532 +1081 +988 +1291 +1097 +1532 +1134 +1291 +1288 +1132 +977 +1291 +1073 +1132 +1277 +1277 +1061 +1132 +1277 +1291 +1058 +1277 +1277 +1058 +1019 +1008 +1322 +1058 +1285 +1277 +1285 +1288 +1285 +1288 +1291 +1097 +1291 +1293 +1293 +1293 +1503 +1296 +988 +1093 +1058 +1300 +1277 +1058 +1322 +1048 +1323 +1061 +1277 +1308 +1073 +1308 +1311 +1093 +1095 +1314 +1097 +1316 +1374 +1316 +1293 +1320 +1097 +1322 +1323 +1058 +1032 +1322 +1582 +1277 +1329 +1330 +923 +1329 +1058 +934 +1058 +1322 +1337 +1322 +1409 +1582 +1449 +1342 +1343 +1323 +1345 +1346 +1330 +1348 +1369 +1337 +1351 +1329 +1191 +1195 +1355 +1356 +1345 +1358 +1359 +1348 +1361 +1382 +1351 +1364 +1419 +1409 +1449 +1342 +1369 +1082 +1371 +1372 +1373 +1374 +1373 +1083 +1391 +1372 +1369 +1372 +1381 +1382 +915 +1384 +1382 +1386 +1387 +1388 +1419 +1386 +1391 +1392 +1382 +1372 +1419 +1195 +1369 +1374 +1388 +1374 +1401 +1387 +1337 +1191 +1405 +1382 +1584 +1667 +1409 +1410 +1369 +1577 +1767 +1191 +1405 +1382 +1486 +1449 +1419 +1734 +1480 +1734 +1767 +1449 +1486 +1489 +1427 +1449 +1486 +1430 +1449 +1432 +1486 +1586 +1435 +1478 +1409 +1582 +1584 +1577 +1441 +1442 +1480 +1735 +1480 +1387 +1447 +1441 +1449 +1441 +1451 +1452 +1449 +1430 +1329 +1462 +1032 +1662 +1459 +1323 +1461 +1462 +1463 +1668 +1465 +1466 +1469 +1468 +1469 +1478 +1471 +1329 +1479 +923 +1582 +1058 +1330 +1478 +1479 +1480 +1489 +1480 +1372 +1484 +1737 +1486 +1490 +1488 +1489 +1490 +1480 +1441 +1097 +1316 +1447 +1486 +1441 +1498 +1449 +1277 +1501 +1293 +1503 +1293 +1736 +1372 +1288 +1449 +1486 +1277 +1511 +1736 +1097 +1514 +1093 +1452 +1452 +1463 +1519 +1466 +1293 +1522 +1532 +1532 +1525 +1073 +1463 +1285 +1277 +1532 +1277 +1532 +1058 +1532 +1058 +1058 +1322 +1322 +1463 +1461 +1532 +1461 +1532 +1532 +1532 +1514 +1061 +1322 +1532 +1322 +1277 +1058 +1322 +727 +510 +1767 +1767 +1767 +436 +1734 +1647 +733 +510 +1577 +1565 +1667 +1409 +1486 +1584 +1667 +1679 +1614 +1591 +1432 +1191 +1449 +1577 +1801 +1579 +1801 +1581 +1582 +1486 +1584 +1614 +1586 +1824 +1588 +1582 +1625 +1591 +1625 +1814 +1814 +1814 +1814 +1597 +1577 +1795 +1600 +1584 +1430 +1603 +1625 +1715 +1606 +1614 +1694 +1430 +727 +1679 +1614 +1597 +1614 +1726 +1814 +733 +551 +1625 +1620 +727 +703 +551 +1734 +1625 +1708 +551 +1734 +1374 +1734 +1734 +1632 +1767 +1634 +1577 +1769 +1637 +1734 +1767 +1640 +1734 +733 +1781 +551 +1734 +1734 +1734 +1648 +1767 +1781 +551 +733 +1480 +1734 +1734 +1767 +1657 +1658 +1659 +1330 +1058 +1662 +1678 +1664 +1691 +1666 +1667 +1668 +1669 +1667 +1679 +1462 +1673 +1750 +1679 +1814 +1811 +1678 +1679 +1679 +1681 +1783 +1683 +1614 +1685 +1814 +1805 +1688 +1786 +1688 +1691 +1430 +1693 +1694 +1792 +1430 +1750 +1679 +1786 +1811 +1614 +1685 +551 +1805 +1705 +1781 +1705 +1708 +1708 +1771 +1767 +1480 +1767 +1714 +1715 +1783 +1717 +1718 +1736 +1720 +1734 +1679 +710 +551 +1725 +1726 +1786 +1726 +1734 +1734 +1374 +1667 +1725 +1734 +1735 +1736 +1737 +1746 +1743 +1805 +1811 +1746 +1743 +1744 +1705 +1746 +1840 +1862 +1786 +1750 +1679 +1705 +1798 +1750 +1755 +1679 +1805 +1746 +1840 +1811 +1814 +1734 +1734 +692 +692 +1766 +1767 +1734 +1769 +1708 +1771 +1667 +1480 +1736 +1775 +1734 +1769 +1374 +1734 +1766 +1781 +1374 +1783 +1734 +1715 +1786 +1688 +1726 +1789 +1373 +1726 +1792 +1667 +1694 +1795 +1371 +1705 +1798 +1838 +1705 +1801 +1679 +1803 +1705 +1805 +1806 +1824 +1681 +1750 +1679 +1811 +1679 +1813 +1814 +1814 +1816 +1801 +1688 +1819 +1667 +1679 +1479 +1823 +1824 +1667 +1826 +1323 +1814 +1582 +1813 +1736 +1832 +1734 +1736 +1503 +1767 +1858 +1708 +1862 +1734 +1708 +1736 +1862 +1927 +1845 +1846 +1736 +1927 +1097 +1767 +1851 +1736 +1781 +1734 +1708 +1744 +692 +1858 +1927 +1781 +1744 +1862 +1744 +1864 +1503 +1866 +1503 +1503 +1927 +1715 +1864 +1726 +1803 +1744 +1291 +1316 +1786 +1715 +1894 +1726 +1736 +1736 +1883 +1884 +1503 +1293 +1073 +1892 +1503 +1862 +1862 +1892 +1786 +1894 +1503 +1511 +1293 +1898 +1783 +1894 +1901 +1694 +1927 +1705 +1705 +1927 +1927 +1288 +1314 +1798 +1911 +1736 +1288 +1914 +1922 +460 +1694 +1918 +1522 +1291 +1921 +1922 +1277 +1715 +1918 +1694 +1927 +1503 +1792 +1927 +1931 +1277 +1532 +1285 +1657 +1803 +1277 +1532 +460 +1940 +1952 +1814 +1805 +1532 +1945 +1946 +1277 +1277 +1532 +1532 +1951 +1952 +1300 +1814 +1058 +1945 +1705 +1894 +460 +1679 +1814 +1532 +1032 +1285 +1277 +1966 +1806 +1894 +1532 +1894 +1894 +1532 +1277 +1322 +1277 +1322 +1951 +1894 +1679 +1803 +1927 +1532 +1532 +277 +1285 +1986 +1277 +1277 +1285 +1940 +1277 +1814 +1532 +1994 +1532 +1532 +1997 +1277 +1927 +1679 +1532 +2002 diff --git a/data/jagmesh7_cluster.mtx b/data/jagmesh7_cluster.mtx new file mode 100644 index 0000000000..2500ffafb1 --- /dev/null +++ b/data/jagmesh7_cluster.mtx @@ -0,0 +1,1141 @@ +%%MatrixMarket matrix array integer general +%%GraphBLAS type int64_t +1138 1 1138 +0 +0 +0 +2 +2 +6 +6 +6 +8 +8 +8 +12 +12 +12 +12 +0 +0 +0 +0 +2 +2 +2 +0 +2 +8 +12 +8 +12 +0 +29 +29 +29 +34 +34 +34 +34 +34 +6 +6 +0 +29 +29 +34 +2 +2 +34 +2 +6 +6 +0 +0 +0 +0 +0 +0 +0 +56 +56 +56 +34 +0 +0 +0 +0 +29 +29 +56 +29 +56 +29 +0 +71 +71 +71 +75 +75 +75 +77 +77 +77 +853 +56 +71 +71 +71 +56 +56 +77 +56 +77 +56 +0 +0 +0 +0 +0 +154 +0 +98 +98 +98 +75 +0 +0 +0 +0 +71 +71 +98 +71 +98 +71 +154 +113 +113 +113 +113 +848 +848 +119 +119 +75 +75 +98 +113 +113 +113 +98 +98 +119 +98 +119 +75 +154 +134 +134 +134 +134 +833 +833 +140 +140 +140 +113 +113 +134 +134 +134 +113 +113 +140 +113 +140 +113 +154 +154 +154 +154 +154 +154 +154 +161 +161 +161 +181 +154 +154 +154 +154 +134 +134 +161 +134 +161 +134 +154 +176 +176 +176 +181 +181 +181 +181 +181 +181 +181 +161 +176 +176 +181 +161 +161 +181 +161 +181 +181 +154 +154 +154 +154 +201 +201 +201 +203 +203 +203 +181 +154 +154 +154 +154 +176 +176 +203 +176 +203 +176 +201 +201 +201 +201 +201 +280 +201 +224 +224 +224 +181 +201 +201 +201 +201 +203 +203 +224 +203 +224 +181 +280 +239 +239 +239 +239 +239 +239 +245 +245 +245 +369 +224 +239 +239 +239 +224 +224 +245 +224 +245 +224 +280 +260 +260 +260 +260 +385 +385 +266 +266 +266 +239 +239 +260 +260 +260 +239 +239 +266 +239 +266 +239 +280 +280 +280 +280 +285 +285 +285 +287 +287 +287 +260 +280 +280 +280 +280 +260 +260 +287 +260 +287 +260 +285 +285 +285 +285 +285 +285 +285 +308 +308 +308 +327 +285 +285 +285 +285 +287 +287 +308 +287 +308 +287 +285 +323 +323 +323 +327 +327 +327 +327 +327 +327 +327 +327 +308 +308 +308 +327 +308 +323 +327 +323 +327 +285 +285 +285 +285 +285 +285 +285 +350 +350 +350 +327 +285 +285 +285 +285 +323 +323 +350 +323 +350 +323 +239 +365 +365 +365 +369 +369 +369 +369 +369 +369 +369 +369 +245 +245 +245 +369 +245 +365 +369 +365 +369 +385 +385 +385 +385 +385 +385 +385 +392 +392 +392 +239 +385 +385 +385 +385 +266 +266 +392 +266 +392 +266 +239 +407 +407 +407 +412 +412 +412 +412 +412 +369 +369 +239 +407 +407 +412 +365 +365 +412 +365 +369 +369 +385 +428 +428 +428 +412 +239 +392 +392 +392 +407 +392 +428 +407 +428 +407 +285 +443 +443 +443 +447 +447 +447 +447 +327 +327 +327 +327 +350 +350 +350 +327 +350 +443 +447 +443 +447 +285 +285 +285 +285 +285 +285 +285 +470 +470 +470 +447 +285 +285 +285 +285 +443 +443 +470 +443 +470 +443 +285 +485 +485 +485 +490 +490 +490 +490 +490 +447 +447 +447 +470 +470 +470 +447 +470 +485 +490 +485 +490 +285 +285 +285 +285 +510 +510 +510 +512 +512 +512 +490 +485 +485 +485 +285 +512 +485 +285 +512 +285 +285 +510 +510 +510 +510 +510 +624 +510 +533 +533 +533 +547 +512 +512 +512 +510 +533 +512 +510 +533 +510 +510 +547 +547 +547 +547 +547 +547 +531 +554 +554 +547 +547 +547 +547 +547 +547 +547 +533 +533 +533 +533 +533 +385 +385 +385 +547 +547 +547 +574 +574 +574 +412 +385 +385 +547 +547 +428 +428 +574 +428 +574 +412 +531 +589 +589 +589 +609 +574 +574 +574 +547 +589 +554 +554 +589 +554 +531 +624 +604 +604 +604 +609 +609 +609 +609 +609 +609 +609 +609 +589 +589 +589 +609 +589 +604 +609 +604 +609 +624 +624 +624 +624 +629 +629 +629 +631 +631 +631 +609 +604 +604 +604 +624 +631 +604 +624 +631 +624 +624 +629 +629 +629 +629 +629 +629 +629 +652 +652 +652 +666 +631 +631 +631 +629 +652 +631 +629 +652 +629 +629 +666 +666 +666 +666 +666 +666 +629 +673 +673 +666 +666 +666 +666 +666 +666 +666 +652 +652 +652 +652 +652 +629 +629 +629 +629 +629 +1123 +629 +694 +694 +666 +666 +666 +673 +673 +629 +694 +673 +629 +694 +629 +629 +708 +708 +708 +666 +666 +666 +1123 +715 +715 +708 +708 +708 +708 +666 +666 +708 +694 +694 +694 +694 +694 +729 +729 +729 +715 +708 +708 +1123 +736 +736 +729 +729 +729 +715 +715 +708 +736 +715 +715 +736 +715 +715 +729 +729 +751 +751 +755 +755 +755 +755 +708 +708 +708 +729 +729 +751 +755 +729 +708 +708 +708 +708 +708 +818 +772 +772 +772 +755 +755 +729 +729 +778 +778 +1067 +772 +772 +751 +751 +778 +751 +751 +778 +751 +729 +818 +793 +793 +793 +797 +797 +797 +797 +755 +755 +755 +772 +793 +793 +797 +772 +755 +755 +755 +755 +755 +818 +814 +814 +814 +797 +818 +818 +818 +818 +818 +818 +814 +814 +793 +818 +793 +793 +818 +793 +818 +833 +833 +833 +797 +797 +140 +140 +140 +833 +814 +140 +833 +814 +797 +797 +848 +848 +848 +848 +853 +853 +853 +855 +855 +75 +75 +75 +119 +119 +848 +855 +119 +848 +855 +848 +848 +853 +853 +853 +853 +853 +853 +77 +77 +75 +853 +77 +855 +853 +855 +853 +6 +6 +6 +6 +6 +947 +6 +891 +891 +891 +12 +8 +8 +8 +6 +891 +8 +6 +891 +6 +6 +947 +906 +906 +906 +910 +910 +910 +910 +12 +12 +12 +12 +891 +891 +891 +12 +891 +906 +910 +906 +910 +947 +927 +927 +927 +927 +927 +927 +933 +933 +933 +910 +906 +927 +927 +927 +906 +906 +933 +906 +933 +906 +947 +947 +947 +947 +952 +952 +952 +954 +954 +954 +927 +947 +947 +947 +947 +927 +927 +954 +927 +954 +927 +927 +969 +969 +969 +973 +973 +973 +973 +910 +910 +910 +910 +933 +933 +933 +910 +933 +969 +973 +969 +973 +952 +952 +952 +952 +952 +1067 +952 +996 +996 +996 +927 +952 +952 +952 +952 +954 +954 +996 +954 +996 +954 +927 +1011 +1011 +1011 +1015 +1015 +1015 +1015 +973 +973 +973 +927 +1011 +1011 +1015 +969 +969 +1015 +969 +973 +973 +1067 +1032 +1032 +1032 +1015 +927 +996 +996 +996 +1011 +996 +1032 +1011 +1032 +1011 +1067 +1047 +1047 +1047 +1052 +1052 +1052 +1052 +1052 +1015 +1015 +1015 +1032 +1032 +1032 +1015 +1032 +1047 +1052 +1047 +1052 +1067 +1067 +1067 +1067 +1067 +1067 +1067 +1074 +1074 +1074 +1052 +1067 +1067 +1067 +1067 +1047 +1047 +1074 +1047 +1074 +1047 +1067 +1089 +1089 +729 +729 +729 +1094 +1094 +1094 +1123 +1074 +1089 +1089 +729 +1074 +1074 +1094 +1074 +1094 +1074 +1067 +1067 +1067 +1067 +1067 +1067 +1067 +1067 +1067 +1089 +778 +778 +1089 +778 +729 +1123 +1123 +1123 +1123 +1123 +729 +736 +736 +1123 +1094 +736 +1123 +1094 +1123 +1123 diff --git a/data/karate_cluster.mtx b/data/karate_cluster.mtx new file mode 100644 index 0000000000..a65fd77b7d --- /dev/null +++ b/data/karate_cluster.mtx @@ -0,0 +1,37 @@ +%%MatrixMarket matrix array integer general +%%GraphBLAS type int64_t +34 1 34 +11 +17 +9 +12 +4 +16 +16 +7 +30 +9 +4 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +24 +24 +24 +26 +24 +28 +26 +30 +24 +14 +26 diff --git a/data/mcl_cluster.mtx b/data/mcl_cluster.mtx new file mode 100644 index 0000000000..90670611a4 --- /dev/null +++ b/data/mcl_cluster.mtx @@ -0,0 +1,13 @@ +%%MatrixMarket matrix array integer general +%%GraphBLAS type int64_t +10 1 10 +0 +0 +0 +0 +5 +5 +5 +8 +8 +8 diff --git a/data/west0067_cluster.mtx b/data/west0067_cluster.mtx new file mode 100644 index 0000000000..e873bcd595 --- /dev/null +++ b/data/west0067_cluster.mtx @@ -0,0 +1,70 @@ +%%MatrixMarket matrix array integer general +%%GraphBLAS type int64_t +67 1 67 +9 +9 +11 +10 +9 +10 +6 +7 +8 +9 +10 +11 +10 +11 +10 +11 +10 +9 +10 +9 +11 +10 +9 +10 +9 +11 +10 +9 +10 +9 +30 +31 +32 +33 +34 +35 +9 +11 +11 +10 +33 +10 +9 +43 +31 +45 +46 +53 +48 +49 +50 +51 +52 +53 +10 +50 +9 +50 +11 +43 +60 +9 +9 +9 +48 +53 +66 diff --git a/experimental/algorithm/LAGr_MarkovClustering.c b/experimental/algorithm/LAGr_MarkovClustering.c index c31bd07161..840f5ad6e9 100644 --- a/experimental/algorithm/LAGr_MarkovClustering.c +++ b/experimental/algorithm/LAGr_MarkovClustering.c @@ -140,7 +140,6 @@ int LAGr_MarkovClustering( double mse = 0; GRB_TRY(GxB_Matrix_eWiseUnion(MSE, NULL, NULL, GrB_MINUS_FP32, T, zero_FP32, T_prev, zero_FP32, NULL)); -// GRB_TRY(GrB_eWiseMult(MSE, NULL, NULL, GrB_TIMES_FP32, MSE, MSE, NULL)); GRB_TRY(GrB_apply(MSE, NULL, NULL, GxB_POW_FP32, MSE, (double) 2, NULL)); GRB_TRY(GrB_reduce(&mse, NULL, GrB_PLUS_MONOID_FP32, MSE, NULL)); diff --git a/experimental/algorithm/LAGr_Modularity.c b/experimental/algorithm/LAGr_Modularity.c index 4ee15a0856..a65768dc20 100644 --- a/experimental/algorithm/LAGr_Modularity.c +++ b/experimental/algorithm/LAGr_Modularity.c @@ -41,9 +41,10 @@ GrB_free(&k_out); \ GrB_free(&in_degree); \ GrB_free(&out_degree); \ + GrB_free(&A); \ GrB_free(&CA); \ GrB_free(&C); \ - GrB_free(&ONE_BOOL); \ + GrB_free(&ONE_INT64); \ LAGraph_Free((void **)&lX, NULL); \ LAGraph_Free((void **)&k_outX, NULL); \ LAGraph_Free((void **)&k_inX, NULL); \ @@ -63,35 +64,50 @@ int LAGr_Modularity( // Inputs double resolution, // resolution parameter GrB_Vector c, // input cluster vector - GrB_Matrix A, // adjacency matrix of original graph from which the - // clustering was obtained + LAGraph_Graph G, // original graph from which clustering was obtained char *msg) { GrB_Vector l = NULL; GrB_Vector vmask = NULL; GrB_Vector k_in = NULL, k_out = NULL; GrB_Vector out_degree = NULL, in_degree = NULL; - GrB_Matrix C = NULL, CA = NULL; - GrB_Scalar ONE_BOOL = NULL; + GrB_Matrix C = NULL, CA = NULL, A = NULL; + GrB_Scalar ONE_INT64 = NULL; GrB_Index *lX = NULL, *k_outX = NULL, *k_inX = NULL; + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + LG_CLEAR_MSG; + LG_ASSERT_MSG(mod_handle != NULL, GrB_NULL_POINTER, "mod_handle is NULL"); - LG_ASSERT_MSG(resolution >= 0, -1006, + LG_ASSERT_MSG(resolution >= 0, GrB_INVALID_VALUE, "resolution parameter must be non-negative"); + LG_TRY(LAGraph_CheckGraph(G, msg)); + + GrB_Index n, nedges; + GRB_TRY(GrB_Matrix_nrows(&n, G->A)); + + // Do not consider edge weights for modularity + // FUTURE: There is a way to consider edge weights in modularity calculations, + // so could give users the option to pass in a 'weights' parameter specifying + // that edge weights should be used in the calculations. + GRB_TRY(GrB_Matrix_new(&A, GrB_INT64, n, n)); + GRB_TRY(GrB_apply(A, NULL, NULL, GxB_ONE_INT64, G->A, NULL)); + // remove self-edges, not relevant to clustering metrics GRB_TRY(GrB_select(A, NULL, NULL, GrB_OFFDIAG, A, 0, NULL)); - GrB_Index n, nedges; - GRB_TRY(GrB_Matrix_nrows(&n, A)); GRB_TRY(GrB_Matrix_nvals(&nedges, A)); //-------------------------------------------------------------------------- // initializations //-------------------------------------------------------------------------- - GRB_TRY(GrB_Matrix_new(&C, GrB_BOOL, n, n)); + GRB_TRY(GrB_Matrix_new(&C, GrB_INT64, n, n)); GRB_TRY(GrB_Matrix_new(&CA, GrB_INT64, n, n)); GRB_TRY(GrB_Vector_new(&l, GrB_INT64, n)); GRB_TRY(GrB_Vector_new(&vmask, GrB_INT64, n)); @@ -99,23 +115,23 @@ int LAGr_Modularity( GRB_TRY(GrB_Vector_new(&k_out, GrB_INT64, n)); GRB_TRY(GrB_Vector_new(&out_degree, GrB_INT64, n)); GRB_TRY(GrB_Vector_new(&in_degree, GrB_INT64, n)); - GRB_TRY(GrB_Scalar_new(&ONE_BOOL, GrB_BOOL)); + GRB_TRY(GrB_Scalar_new(&ONE_INT64, GrB_INT64)); - GRB_TRY(GrB_Scalar_setElement_BOOL(ONE_BOOL, (bool)1)); + GRB_TRY(GrB_Scalar_setElement_INT64(ONE_INT64, (int64_t)1)); - // Convert the cluster vector to a boolean matrix C where + // Convert the cluster vector to a uint64_t matrix C where // C(i, j) = 1 if and only if vertex j is in cluster i GrB_Index *cI, *cX; LAGRAPH_TRY(LAGraph_Malloc((void **)&cI, n, sizeof(GrB_Index), msg)); LAGRAPH_TRY(LAGraph_Malloc((void **)&cX, n, sizeof(GrB_Index), msg)); GRB_TRY(GrB_Vector_extractTuples_INT64(cI, cX, &n, c)); - GRB_TRY(GxB_Matrix_build_Scalar(C, cX, cI, ONE_BOOL, n)); + GRB_TRY(GxB_Matrix_build_Scalar(C, cX, cI, ONE_INT64, n)); GrB_Matrix_wait(C, GrB_MATERIALIZE); LAGraph_Free((void **)&cI, NULL); LAGraph_Free((void **)&cX, NULL); // Calculate actual number of intra-cluster edges - GRB_TRY(GrB_mxm(CA, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_INT64, C, A, NULL)); + GRB_TRY(GrB_mxm(CA, NULL, NULL, LAGraph_plus_one_int64, C, A, NULL)); GRB_TRY(GrB_mxm(CA, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_INT64, CA, C, GrB_DESC_T1)); GRB_TRY(GxB_Vector_diag(l, CA, 0, NULL)); @@ -189,4 +205,4 @@ int LAGr_Modularity( LG_FREE_WORK; return (GrB_SUCCESS); -} \ No newline at end of file +} diff --git a/experimental/algorithm/LAGr_PartitionQuality.c b/experimental/algorithm/LAGr_PartitionQuality.c index 91db2a87ef..5e87249515 100644 --- a/experimental/algorithm/LAGr_PartitionQuality.c +++ b/experimental/algorithm/LAGr_PartitionQuality.c @@ -22,6 +22,9 @@ // very simple cluster quality metrics which can be used to evaluate the quality // of a clustering, primarily based on the idea of intra-cluster density. +// Note that coverage and performance are counting problems. Therefore, if a +// weighted graph is passed to this function, edge weights are ignored. + // https://arxiv.org/abs/0906.0612 pp. 15 #define LG_FREE_WORK \ @@ -30,8 +33,7 @@ GrB_free(&k); \ GrB_free(&C); \ GrB_free(&CA); \ - GrB_free(&AT); \ - GrB_free(&ONE_BOOL); \ + GrB_free(&ONE_INT64); \ } #define LG_FREE_ALL \ @@ -39,6 +41,8 @@ LG_FREE_WORK; \ } +#define DEBUG 0 + #include "LG_internal.h" #include @@ -47,9 +51,8 @@ int LAGr_PartitionQuality( double *cov, // coverage output, can be NULL double *perf, // performance output, can be NULL // Inputs - GrB_Vector c, // input cluster vector - GrB_Matrix A, // adjacency matrix of original graph from which the - // clustering was obtained + GrB_Vector c, // input cluster vector + LAGraph_Graph G, // original graph from which the clustering was obtained char *msg) { GrB_Vector trace = NULL; @@ -57,30 +60,48 @@ int LAGr_PartitionQuality( GrB_Matrix C = NULL; GrB_Matrix CA = NULL; - GrB_Scalar ONE_BOOL = NULL; - - GrB_Matrix AT = NULL; + GrB_Scalar ONE_INT64 = NULL; GrB_Index n, nedges; GrB_Index n_intraEdges, n_interEdges, n_interNonEdges, sum_k2; + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + LG_CLEAR_MSG; + LG_ASSERT_MSG(cov != NULL || perf != NULL, GrB_NULL_POINTER, "cov and perf " "cannot both be NULL"); + LG_TRY(LAGraph_CheckGraph(G, msg)); + + LG_ASSERT_MSG (G->is_symmetric_structure != LAGRAPH_UNKNOWN, + LAGRAPH_NOT_CACHED, + "G->is_symmetric_structure is required") ; + + GrB_Matrix A = G->A; + // Delete self-edges, not relevant to these clustering metrics GRB_TRY(GrB_select(A, NULL, NULL, GrB_OFFDIAG, A, 0, NULL)); +#if DEBUG + FILE *f = fopen("./data/pp_sanitized_data.mtx", "w"); + LAGRAPH_TRY(LAGraph_MMWrite(A, f, NULL, msg)); + fclose(f); +#endif + GRB_TRY(GrB_Matrix_nrows(&n, A)); GRB_TRY(GrB_Matrix_nvals(&nedges, A)); - GRB_TRY(GrB_Matrix_new(&C, GrB_BOOL, n, n)); + GRB_TRY(GrB_Matrix_new(&C, GrB_INT64, n, n)); GRB_TRY(GrB_Matrix_new(&CA, GrB_INT64, n, n)); GRB_TRY(GrB_Vector_new(&trace, GrB_INT64, n)); GRB_TRY(GrB_Vector_new(&k, GrB_INT64, n)); - GRB_TRY(GrB_Scalar_new(&ONE_BOOL, GrB_BOOL)); + GRB_TRY(GrB_Scalar_new(&ONE_INT64, GrB_INT64)); - GRB_TRY(GrB_Scalar_setElement_BOOL(ONE_BOOL, (bool)1)); + GRB_TRY(GrB_Scalar_setElement_BOOL(ONE_INT64, (uint64_t)1)); // convert the cluster vector to a boolean matrix C where // C(i, j) = 1 if and only if vertex j is in cluster i @@ -88,16 +109,12 @@ int LAGr_PartitionQuality( LAGRAPH_TRY(LAGraph_Malloc((void **)&cI, n, sizeof(GrB_Index), msg)); LAGRAPH_TRY(LAGraph_Malloc((void **)&cX, n, sizeof(GrB_Index), msg)); GRB_TRY(GrB_Vector_extractTuples_INT64(cI, cX, &n, c)); - GRB_TRY(GxB_Matrix_build_Scalar(C, cX, cI, ONE_BOOL, n)); + GRB_TRY(GxB_Matrix_build_Scalar(C, cX, cI, ONE_INT64, n)); GrB_Matrix_wait(C, GrB_MATERIALIZE); LAGraph_Free((void **)&cI, NULL); LAGraph_Free((void **)&cX, NULL); - // check if graph is undirected (that is, is A symmetric) - bool is_undirected; - GRB_TRY(GrB_Matrix_new(&AT, GrB_BOOL, n, n)); - GRB_TRY(GrB_transpose(AT, NULL, NULL, A, NULL)); - LAGRAPH_TRY(LAGraph_Matrix_IsEqual(&is_undirected, A, AT, msg)); + bool is_undirected = (G->is_symmetric_structure == LAGraph_TRUE); // k = sum(C) .^ 2 GRB_TRY(GrB_reduce(k, NULL, NULL, GrB_PLUS_MONOID_INT64, C, NULL)); @@ -106,10 +123,12 @@ int LAGr_PartitionQuality( // sum_k2 = total number of possible intra-cluster edges GRB_TRY(GrB_reduce(&sum_k2, NULL, GrB_PLUS_MONOID_INT64, k, NULL)); - // Calculate actual number of intra-cluster edges - GRB_TRY(GrB_mxm(CA, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_INT64, C, A, NULL)); + // Calculate actual number of intra-cluster edges, if A is weighted + // then we ignore the weights and just count the number of edges as + // performance and coverage are inherently counting problems + GRB_TRY(GrB_mxm(CA, NULL, NULL, LAGraph_plus_one_int64, C, A, NULL)); GRB_TRY(GrB_mxm(CA, NULL, NULL, GrB_PLUS_TIMES_SEMIRING_INT64, CA, C, - GrB_DESC_RT1)); + GrB_DESC_T1)); GRB_TRY(GxB_Vector_diag(trace, CA, 0, NULL)); GRB_TRY( @@ -148,4 +167,4 @@ int LAGr_PartitionQuality( LG_FREE_WORK; return (GrB_SUCCESS); -} \ No newline at end of file +} diff --git a/experimental/benchmark/mcl_demo.c b/experimental/benchmark/mcl_demo.c index 6660c40ae0..d3df41717e 100644 --- a/experimental/benchmark/mcl_demo.c +++ b/experimental/benchmark/mcl_demo.c @@ -38,6 +38,8 @@ LAGraph_Free((void **)&cX, NULL); \ } +#define IO 0 + int main(int argc, char **argv) { @@ -65,7 +67,7 @@ int main(int argc, char **argv) char *matrix_name = (argc > 1) ? argv[1] : "stdin"; LAGRAPH_TRY( - readproblem(&G, NULL, false, true, true, GrB_FP32, false, argc, argv)); + readproblem(&G, NULL, false, false, false, NULL, false, argc, argv)); GrB_Index n, nvals; GRB_TRY(GrB_Matrix_nrows(&n, G->A)); @@ -96,14 +98,14 @@ int main(int argc, char **argv) double cov, perf, mod; tt = LAGraph_WallClockTime(); - LAGRAPH_TRY(LAGr_PartitionQuality(&cov, &perf, c, G->A, msg)); + LAGRAPH_TRY(LAGr_PartitionQuality(&cov, &perf, c, G, msg)); tt = LAGraph_WallClockTime() - tt; printf("\npartition quality run time %g sec\n\tcoverage = " "%f\n\tperformance = %f\n", tt, cov, perf); tt = LAGraph_WallClockTime(); - LAGRAPH_TRY(LAGr_Modularity(&mod, (double)1, c, G->A, msg)); + LAGRAPH_TRY(LAGr_Modularity(&mod, (double)1, c, G, msg)); tt = LAGraph_WallClockTime() - tt; printf("modularity run time %g sec\n\tmodularity = %f\n", tt, mod); @@ -126,6 +128,12 @@ int main(int argc, char **argv) GxB_print(vpc_sorted, GxB_SHORT); +#if IO + FILE *f = fopen("./data/pp_out.mtx", "w"); + LAGRAPH_TRY(LAGraph_MMWrite((GrB_Matrix)c, f, NULL, msg)); + fclose(f); +#endif + LG_FREE_ALL; LAGRAPH_TRY(LAGraph_Finalize(msg)); return (GrB_SUCCESS); diff --git a/experimental/benchmark/peer_pressure_demo.c b/experimental/benchmark/peer_pressure_demo.c index 19a46b9363..06056c0a5f 100644 --- a/experimental/benchmark/peer_pressure_demo.c +++ b/experimental/benchmark/peer_pressure_demo.c @@ -24,7 +24,6 @@ #include "LAGraphX.h" #include "LG_Xtest.h" - #define LG_FREE_ALL \ { \ LAGraph_Delete(&G, NULL); \ @@ -37,6 +36,8 @@ LAGraph_Free((void **)&cX, NULL); \ } +#define IO 0 + int main(int argc, char **argv) { @@ -64,12 +65,12 @@ int main(int argc, char **argv) char *matrix_name = (argc > 1) ? argv[1] : "stdin"; LAGRAPH_TRY( - readproblem(&G, NULL, false, true, true, NULL, false, argc, argv)); + readproblem(&G, NULL, false, false, false, NULL, false, argc, argv)); GrB_Index n, nvals; GRB_TRY(GrB_Matrix_nrows(&n, G->A)); GRB_TRY(GrB_Matrix_nvals(&nvals, G->A)); - + //-------------------------------------------------------------------------- // initializations //-------------------------------------------------------------------------- @@ -86,9 +87,10 @@ int main(int argc, char **argv) //-------------------------------------------------------------------------- // compute check result + c = NULL; double tt = LAGraph_WallClockTime(); LAGRAPH_TRY( - LAGr_PeerPressureClustering(&c, false, false, 0.0001, 50, G, msg)); + LAGr_PeerPressureClustering(&c, true, false, 0.0001, 50, G, msg)); tt = LAGraph_WallClockTime() - tt; printf("peer pressure run time %g sec\n", tt); @@ -96,14 +98,14 @@ int main(int argc, char **argv) double cov, perf, mod; tt = LAGraph_WallClockTime(); - LAGRAPH_TRY(LAGr_PartitionQuality(&cov, &perf, c, G->A, msg)); + LAGRAPH_TRY(LAGr_PartitionQuality(&cov, &perf, c, G, msg)); tt = LAGraph_WallClockTime() - tt; printf("\npartition quality run time %g sec\n\tcoverage = " "%f\n\tperformance = %f\n", tt, cov, perf); tt = LAGraph_WallClockTime(); - LAGRAPH_TRY(LAGr_Modularity(&mod, (double)1, c, G->A, msg)); + LAGRAPH_TRY(LAGr_Modularity(&mod, (double)1, c, G, msg)); tt = LAGraph_WallClockTime() - tt; printf("modularity run time %g sec\n\tmodularity = %f\n", tt, mod); @@ -126,6 +128,12 @@ int main(int argc, char **argv) GxB_print(vpc_sorted, GxB_SHORT); +#if IO + FILE *f = fopen("./data/pp_out.mtx", "w"); + LAGRAPH_TRY(LAGraph_MMWrite((GrB_Matrix)c, f, NULL, msg)); + fclose(f); +#endif + LG_FREE_ALL; LAGRAPH_TRY(LAGraph_Finalize(msg)); return (GrB_SUCCESS); diff --git a/experimental/test/test_mcl.c b/experimental/test/test_mcl.c new file mode 100644 index 0000000000..a02e768641 --- /dev/null +++ b/experimental/test/test_mcl.c @@ -0,0 +1,163 @@ +//---------------------------------------------------------------------------- +// LAGraph/src/test/test_mcl.c: test cases for Markov Clustering +// ---------------------------------------------------------------------------- + +// 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 Cameron Quilici, Texas A&M University + +//----------------------------------------------------------------------------- + +#include +#include + +#include "LG_Xtest.h" +#include +#include + +char msg[LAGRAPH_MSG_LEN]; + +LAGraph_Graph G = NULL; +GrB_Matrix A = NULL; +#define LEN 512 +char filename[LEN + 1]; + +typedef struct +{ + const char *name; +} matrix_info; + +const matrix_info files[] = { + {"A.mtx"}, {"jagmesh7.mtx"}, {"west0067.mtx"}, // unsymmetric + {"bcsstk13.mtx"}, {"karate.mtx"}, {"mcl.mtx"}, {""}, +}; + +const int nfiles = 6; + +const double coverage[] = {1.000000, 0.635932, 0.784247, + 0.089424, 0.871795, 0.888889}; + +const double performance[] = {0.714286, 0.990614, 0.282678, + 0.975945, 0.611408, 0.622222}; + +const double modularity[] = {0.000000, 0.624182, 0.033355, + 0.083733, 0.359961, 0.339506}; + +//**************************************************************************** +void test_mcl(void) +{ + LAGraph_Init(msg); + + for (int k = 0;; k++) + { + // load the matrix as A + const char *aname = files[k].name; + if (strlen(aname) == 0) + break; + printf("\n================================== %s:\n", aname); + TEST_CASE(aname); + snprintf(filename, LEN, LG_DATA_DIR "%s", aname); + FILE *f = fopen(filename, "r"); + TEST_CHECK(f != NULL); + OK(LAGraph_MMRead(&A, f, msg)); + + // construct a directed graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)); + TEST_CHECK(A == NULL); + + // compute AT + OK(LAGraph_Cached_AT(G, msg)); + // Needed to compute quality metrics + OK(LAGraph_Cached_IsSymmetricStructure(G, msg)); + + GrB_Vector c = NULL; + + // compute clustering + double cov, perf, mod; + OK(LAGr_MarkovClustering(&c, 2, 2, 0.0001, 1e-8, 100, G, msg)); + OK(LAGr_PartitionQuality(&cov, &perf, c, G, msg)); + OK(LAGr_Modularity(&mod, (double)1, c, G, msg)); + + bool ok_cov = false, ok_perf = false, ok_mod = false; + printf("coverage: %g %g\n", cov, coverage[k]); + printf("perf: %g %g\n", perf, performance[k]); + printf("modularity: %g %g\n", mod, modularity[k]); + ok_cov = (fabs(cov - coverage[k]) < 1e-4) ? true : ok_cov; + ok_perf = (fabs(perf - performance[k]) < 1e-4) ? true : ok_perf; + ok_mod = (fabs(mod - modularity[k]) < 1e-4) ? true : ok_mod; + + TEST_CHECK(ok_cov); + TEST_CHECK(ok_perf); + TEST_CHECK(ok_mod); + + OK(GrB_free(&c)); + + OK(LAGraph_Delete(&G, msg)); + } + + LAGraph_Finalize(msg); +} + +//------------------------------------------------------------------------------ +// test_errors +//------------------------------------------------------------------------------ + +void test_errors(void) +{ + LAGraph_Init(msg); + + snprintf(filename, LEN, LG_DATA_DIR "%s", "karate.mtx"); + FILE *f = fopen(filename, "r"); + TEST_CHECK(f != NULL); + OK(LAGraph_MMRead(&A, f, msg)); + TEST_MSG("Loading of adjacency matrix failed"); + + // construct an undirected graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)); + TEST_CHECK(A == NULL); + + GrB_Vector c = NULL; + int e = 2, i = 2, max_iter = 50; + double prune_thresh = 0.0001, conv_thresh = 1e-8; + + // c is NULL + GrB_Info result = LAGr_MarkovClustering(NULL, e, i, prune_thresh, + conv_thresh, max_iter, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == GrB_NULL_POINTER); + + // e is less than 2 + e = -100; + result = LAGr_MarkovClustering(&c, e, i, prune_thresh, conv_thresh, + max_iter, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == GrB_INVALID_VALUE); + + OK(LAGraph_Delete(&G, msg)); + TEST_CHECK(G == NULL); + + // bad graph, G->A is null + OK(LAGraph_New(&G, NULL, LAGraph_ADJACENCY_UNDIRECTED, msg)); + result = LAGr_MarkovClustering(&c, e, i, prune_thresh, conv_thresh, + max_iter, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == LAGRAPH_INVALID_GRAPH); + + OK(LAGraph_Delete(&G, msg)); + TEST_CHECK(G == NULL); + + LAGraph_Finalize(msg); +} + +//**************************************************************************** + +TEST_LIST = {{"peer_pressure", test_mcl}, + {"peer_pressure_errors", test_errors}, + {NULL, NULL}}; diff --git a/experimental/test/test_peer_pressure.c b/experimental/test/test_peer_pressure.c new file mode 100644 index 0000000000..7bc98c9142 --- /dev/null +++ b/experimental/test/test_peer_pressure.c @@ -0,0 +1,182 @@ +//---------------------------------------------------------------------------- +// LAGraph/src/test/test_peer_pressure.c: test cases for Peer Pressure +// ---------------------------------------------------------------------------- + +// 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 Cameron Quilici, Texas A&M University + +//----------------------------------------------------------------------------- + +#include +#include + +#include "LG_Xtest.h" +#include +#include + +char msg[LAGRAPH_MSG_LEN]; + +LAGraph_Graph G = NULL; +GrB_Matrix A = NULL; +#define LEN 512 +char filename[LEN + 1]; + +typedef struct +{ + const char *name; +} matrix_info; + +const matrix_info files[] = { + {"A.mtx"}, {"jagmesh7.mtx"}, {"west0067.mtx"}, // unsymmetric + {"bcsstk13.mtx"}, {"karate.mtx"}, {"mcl.mtx"}, {""}, +}; + +const int nfiles = 6; + +const double coverage[] = { + 1.000000, 0.653359, 0.181507, 0.048510, 0.243590, 0.833333, + // Start config 2 + 1.000000, 0.644804, 0.123288, 0.695750, 1.000000, 0.722222}; + +const double performance[] = { + 0.714286, 0.989642, 0.841701, 0.977048, 0.887701, 0.866667, + // Start config 2 + 0.714286, 0.992349, 0.914518, 0.934843, 0.139037, 0.777778}; + +const double modularity[] = { + 0.000000, 0.641262, 0.043324, 0.042696, 0.158120, 0.500000, + // Start config 2 + 0.000000, 0.634677, 0.078228, 0.596324, 0.000000, 0.351852}; + +//**************************************************************************** +void test_peer_pressure(void) +{ + LAGraph_Init(msg); + + for (int k = 0;; k++) + { + // load the matrix as A + const char *aname = files[k].name; + if (strlen(aname) == 0) + break; + printf("\n================================== %s:\n", aname); + TEST_CASE(aname); + snprintf(filename, LEN, LG_DATA_DIR "%s", aname); + FILE *f = fopen(filename, "r"); + TEST_CHECK(f != NULL); + OK(LAGraph_MMRead(&A, f, msg)); + // GxB_print (A, 5) ; + + // construct a directed graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)); + TEST_CHECK(A == NULL); + + // compute AT + OK(LAGraph_Cached_AT(G, msg)); + // Needed to compute quality metrics + OK(LAGraph_Cached_IsSymmetricStructure(G, msg)); + + GrB_Vector c = NULL; + + // compute clustering + double cov, perf, mod; + OK(LAGr_PeerPressureClustering(&c, true, false, 0.0001, 50, G, msg)); + OK(LAGr_PartitionQuality(&cov, &perf, c, G, msg)); + OK(LAGr_Modularity(&mod, (double)1, c, G, msg)); + + bool ok_cov = false, ok_perf = false, ok_mod = false; + printf("\nConfiguration 1:\n"); + printf("coverage: %g %g\n", cov, coverage[k]); + printf("perf: %g %g\n", perf, performance[k]); + printf("modularity: %g %g\n", mod, modularity[k]); + ok_cov = (fabs(cov - coverage[k]) < 1e-4) ? true : ok_cov; + ok_perf = (fabs(perf - performance[k]) < 1e-4) ? true : ok_perf; + ok_mod = (fabs(mod - modularity[k]) < 1e-4) ? true : ok_mod; + + TEST_CHECK(ok_cov); + TEST_CHECK(ok_perf); + TEST_CHECK(ok_mod); + + c = NULL; + OK(LAGr_PeerPressureClustering(&c, false, true, 0.0001, 50, G, msg)); + OK(LAGr_PartitionQuality(&cov, &perf, c, G, msg)); + OK(LAGr_Modularity(&mod, (double)1, c, G, msg)); + + ok_cov = false, ok_perf = false, ok_mod = false; + printf("\nConfiguration 2:\n"); + printf("coverage: %g %g\n", cov, coverage[k + nfiles]); + printf("perf: %g %g\n", perf, performance[k + nfiles]); + printf("modularity: %g %g\n", mod, modularity[k + nfiles]); + ok_cov = (fabs(cov - coverage[k + nfiles]) < 1e-4) ? true : ok_cov; + ok_perf = + (fabs(perf - performance[k + nfiles]) < 1e-4) ? true : ok_perf; + ok_mod = (fabs(mod - modularity[k + nfiles]) < 1e-4) ? true : ok_mod; + + TEST_CHECK(ok_cov); + TEST_CHECK(ok_perf); + TEST_CHECK(ok_mod); + + OK(GrB_free(&c)); + + OK(LAGraph_Delete(&G, msg)); + } + + LAGraph_Finalize(msg); +} + +//------------------------------------------------------------------------------ +// test_errors +//------------------------------------------------------------------------------ + +void test_errors(void) +{ + LAGraph_Init(msg); + + snprintf(filename, LEN, LG_DATA_DIR "%s", "karate.mtx"); + FILE *f = fopen(filename, "r"); + TEST_CHECK(f != NULL); + OK(LAGraph_MMRead(&A, f, msg)); + TEST_MSG("Loading of adjacency matrix failed"); + + // construct an undirected graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)); + TEST_CHECK(A == NULL); + + GrB_Vector c = NULL; + bool normalize = false, make_undirected = false; + double thresh = 1e-5; + int max_iter = 100; + + // c is NULL + GrB_Info result = LAGr_PeerPressureClustering( + NULL, normalize, make_undirected, thresh, max_iter, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == GrB_NULL_POINTER); + + // G has no AT + G->AT = NULL; + make_undirected = true; + G->kind = LAGraph_ADJACENCY_DIRECTED; + G->is_symmetric_structure = LAGraph_FALSE; + result = LAGr_PeerPressureClustering(&c, normalize, make_undirected, thresh, + max_iter, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == LAGRAPH_NOT_CACHED); + + OK(LAGraph_Delete(&G, msg)); + LAGraph_Finalize(msg); +} + +//**************************************************************************** + +TEST_LIST = {{"peer_pressure", test_peer_pressure}, + {"peer_pressure_errors", test_errors}, + {NULL, NULL}}; diff --git a/experimental/test/test_quality_metrics.c b/experimental/test/test_quality_metrics.c new file mode 100644 index 0000000000..2f32181a15 --- /dev/null +++ b/experimental/test/test_quality_metrics.c @@ -0,0 +1,228 @@ +//---------------------------------------------------------------------------- +// LAGraph/src/test/test_quality_metrics.c: test cases for both Partition +// Quality and Modularity graph clustering metrics +// ---------------------------------------------------------------------------- + +// 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 Cameron Quilici, Texas A&M University + +//----------------------------------------------------------------------------- + +#include +#include + +#include "LG_Xtest.h" +#include +#include + +char msg[LAGRAPH_MSG_LEN]; + +LAGraph_Graph G = NULL; +GrB_Matrix A = NULL; +GrB_Vector c = NULL; +#define LEN 512 +char filename[LEN + 1]; +char cluster_filename[LEN + 1]; + +typedef struct +{ + const char *name; + const char *cluster_name; +} matrix_info; + +const matrix_info files[] = { + {"A.mtx", "A_cluster.mtx"}, + {"jagmesh7.mtx", "jagmesh7_cluster.mtx"}, + {"west0067.mtx", "west0067_cluster.mtx"}, // unsymmetric + {"bcsstk13.mtx", "bcsstk13_cluster.mtx"}, + {"karate.mtx", "karate_cluster.mtx"}, + {"mcl.mtx", "mcl_cluster.mtx"}, + {"", ""}, +}; + +const int nfiles = 6; + +const double coverage[] = {1.000000, 0.653359, 0.181507, + 0.048510, 0.243590, 0.833333}; + +const double performance[] = {0.714286, 0.989642, 0.841701, + 0.977048, 0.887701, 0.866667}; + +const double modularity[] = {0.000000, 0.641262, 0.043324, + 0.042696, 0.158120, 0.500000}; + +//**************************************************************************** +void test_quality_metrics(void) +{ + LAGraph_Init(msg); + + for (int k = 0;; k++) + { + // load the matrix as A + const char *aname = files[k].name; + const char *aname_cluster = files[k].cluster_name; + if (strlen(aname) == 0 || strlen(aname_cluster) == 0) + break; + printf("\n================================== %s:, %s\n", aname, + aname_cluster); + TEST_CASE(aname); + TEST_CASE(aname_cluster); + snprintf(filename, LEN, LG_DATA_DIR "%s", aname); + FILE *f1 = fopen(filename, "r"); + TEST_CHECK(f1 != NULL); + OK(LAGraph_MMRead(&A, f1, msg)); + + snprintf(cluster_filename, LEN, LG_DATA_DIR "%s", aname_cluster); + FILE *f2 = fopen(cluster_filename, "r"); + TEST_CHECK(f2 != NULL); + OK(LAGraph_MMRead((GrB_Matrix *)&c, f2, msg)); + + // construct a directed graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)); + TEST_CHECK(A == NULL); + + // compute is_symmetric_structure + OK(LAGraph_Cached_IsSymmetricStructure(G, msg)); + TEST_CHECK(G->is_symmetric_structure != LAGRAPH_UNKNOWN); + + // compute quality metrics (coverage and performance) + double cov, perf, mod; + OK(LAGr_PartitionQuality(&cov, NULL, c, G, msg)); + OK(LAGr_PartitionQuality(NULL, &perf, c, G, msg)); + OK(LAGr_Modularity(&mod, (double)1, c, G, msg)); + bool ok_cov = false, ok_perf = false, ok_mod = false; + printf("coverage: %g %g\n", cov, coverage[k]); + printf("perf: %g %g\n", perf, performance[k]); + printf("modularity: %g %g\n", mod, modularity[k]); + ok_cov = (fabs(cov - coverage[k]) < 1e-4) ? true : ok_cov; + ok_perf = (fabs(perf - performance[k]) < 1e-4) ? true : ok_perf; + ok_mod = (fabs(mod - modularity[k]) < 1e-4) ? true : ok_mod; + + TEST_CHECK(ok_cov); + TEST_CHECK(ok_perf); + TEST_CHECK(ok_mod); + + OK(GrB_free(&c)); + + OK(LAGraph_Delete(&G, msg)); + } + + LAGraph_Finalize(msg); +} + +//------------------------------------------------------------------------------ +// test_errors +//------------------------------------------------------------------------------ + +void test_partition_quality_errors(void) +{ + LAGraph_Init(msg); + + snprintf(filename, LEN, LG_DATA_DIR "%s", "west0067.mtx"); + FILE *f1 = fopen(filename, "r"); + TEST_CHECK(f1 != NULL); + OK(LAGraph_MMRead(&A, f1, msg)); + TEST_MSG("Loading of adjacency matrix failed"); + + snprintf(cluster_filename, LEN, LG_DATA_DIR "%s", "west0067_cluster.mtx"); + FILE *f2 = fopen(cluster_filename, "r"); + TEST_CHECK(f2 != NULL); + OK(LAGraph_MMRead((GrB_Matrix *)&c, f2, msg)); + TEST_MSG("Loading of cluster vector failed"); + + // construct an undirected graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)); + TEST_CHECK(A == NULL); + + double cov, perf; + + // both cov and perf are null + GrB_Info result = LAGr_PartitionQuality(NULL, NULL, c, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == GrB_NULL_POINTER); + + // G->is_symmetric_structure is not cached + G->is_symmetric_structure = LAGRAPH_UNKNOWN; + result = LAGr_PartitionQuality(&cov, &perf, c, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == LAGRAPH_NOT_CACHED); + + OK(LAGraph_Delete(&G, msg)); + TEST_CHECK(G == NULL); + + // bad graph, G->A is null + OK(LAGraph_New(&G, NULL, LAGraph_ADJACENCY_UNDIRECTED, msg)); + result = LAGr_PartitionQuality(&cov, &perf, c, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == LAGRAPH_INVALID_GRAPH); + + OK(LAGraph_Delete(&G, msg)); + TEST_CHECK(G == NULL); + + LAGraph_Finalize(msg); +} + +void test_modularity_errors(void) +{ + LAGraph_Init(msg); + + snprintf(filename, LEN, LG_DATA_DIR "%s", "west0067.mtx"); + FILE *f1 = fopen(filename, "r"); + TEST_CHECK(f1 != NULL); + OK(LAGraph_MMRead(&A, f1, msg)); + TEST_MSG("Loading of adjacency matrix failed"); + + snprintf(cluster_filename, LEN, LG_DATA_DIR "%s", "west0067_cluster.mtx"); + FILE *f2 = fopen(cluster_filename, "r"); + TEST_CHECK(f2 != NULL); + OK(LAGraph_MMRead((GrB_Matrix *)&c, f2, msg)); + TEST_MSG("Loading of cluster vector failed"); + + // construct an undirected graph G with adjacency matrix A + OK(LAGraph_New(&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)); + TEST_CHECK(A == NULL); + + double mod; + double resolution = 1; + + // mod is NULL + GrB_Info result = LAGr_Modularity(NULL, resolution, c, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == GrB_NULL_POINTER); + + // resolution parameter is negative + resolution = -1; + result = LAGr_Modularity(&mod, resolution, c, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == GrB_INVALID_VALUE); + resolution = 1; + + OK(LAGraph_Delete(&G, msg)); + TEST_CHECK(G == NULL); + + // bad graph, G->A is null + OK(LAGraph_New(&G, NULL, LAGraph_ADJACENCY_UNDIRECTED, msg)); + result = LAGr_Modularity(&mod, resolution, c, G, msg); + printf("\nresult: %d %s\n", result, msg); + TEST_CHECK(result == LAGRAPH_INVALID_GRAPH); + + OK(LAGraph_Delete(&G, msg)); + TEST_CHECK(G == NULL); + + LAGraph_Finalize(msg); +} + +//**************************************************************************** + +TEST_LIST = {{"quality_metrics", test_quality_metrics}, + {"partition_quality_errors", test_partition_quality_errors}, + {"modularity_errors", test_modularity_errors}, + {NULL, NULL}}; diff --git a/include/LAGraphX.h b/include/LAGraphX.h index 353ffe7f2c..7a638321dd 100644 --- a/include/LAGraphX.h +++ b/include/LAGraphX.h @@ -1199,11 +1199,11 @@ int LAGr_MarkovClustering( LAGRAPHX_PUBLIC int LAGr_PartitionQuality( // Outputs - double *cov, // Coverage - double *perf, // Performance + double *cov, // Coverage + double *perf, // Performance // Inputs - GrB_Vector c, // Cluster vector where c[i] = j means vertex i is in cluster j - GrB_Matrix A, // Adjacency matrix + GrB_Vector c, // Cluster vector where c[i] = j means vertex i is in cluster j + LAGraph_Graph G, // original graph char *msg ); @@ -1214,7 +1214,7 @@ int LAGr_Modularity( // Inputs double gamma, // Resolution parameter GrB_Vector c, // Cluster vector where c[i] = j means vertex i is in cluster j - GrB_Matrix A, // Adjacency matrix + LAGraph_Graph G, // original graph char *msg ) ;